<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Majid Ganji</title>
        <link>https://virgool.io/feed/@majidganji1996</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-08 22:29:05</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/184464/avatar/diJ0Ky.png?height=120&amp;width=120</url>
            <title>Majid Ganji</title>
            <link>https://virgool.io/@majidganji1996</link>
        </image>

                    <item>
                <title>آموزش مجوز های ACL در Linux</title>
                <link>https://virgool.io/@majidganji1996/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D9%85%D8%AC%D9%88%D8%B2-%D9%87%D8%A7%DB%8C-acl-%D8%AF%D8%B1-linux-zm8jy6yw2ww6</link>
                <description>توجه: قبل از مطالعه این مطلب باید به بحث &quot;سطح دسترسی&quot; در لینوکس مسلط باشید.اولین سوالی که با خواندن عنوان مطلب به ذهن‌تان می‌رسید قطعا این است که ACL چیست؟در تعریف ACL می توان گفت  که مخفف access control list است که برای ایجاد دسترسی به کاربر خاصی است که بتواند فایلی رو ویرایش یا اجرا کند یا حتی فایل رو بتواند بخواند بدون این که کاربر رو عضو گروهی کنیم یا حتی گروه جدیدی را ایجاد کنیم. چون نمی‌خواهیم کاربر به اطلاعات کامل گروه مورد نظر دسترسی داشته باشد. برای مثال:ls -l
total 0
-rwx------ 1 root www-data 0 Oct 15 08:36 acl-test.phpمی‌خواهیم کاربر vagrant به فایل acl-test.php دسترسی داشته باشد بدون اضافه کردن کاربر موردنظر به گروه www-data.خب برای اینکار ما از دستور setfacl استفاده میکنیم:sudo setfacl -m u:vagrant:rx acl-test.phpدر دستور بالا ما دسترسی خواندن و اجرا کردن رو به کاربر vagrant دادیم.که -m به معنی تغییر دسترسی هستش که پارمتر u:vagrant:rw رو بهش می‌دهیم که از سه بخش تشکیل شده است که هر بخش با : از هم جدا می‌شود. که u به معنی user است و بعد vagrant نام کاربری و در آخر rx سطح دسترسی مورد نظرمان است.توجه: می توانیم بجای u از g استفاده کنیم برای دسترسی دادن به یک گروه خاصی برای مثال:sudo setfacl -m g:mygroup:rwx acl-test.phpتشخیص فایل هایی که از دسترسی ACL دارند:با استفاده از ls -l  میتوانیم فایل هایی که ACL دارند را  تشخص بدهیم:-rwxr-x---+ 1 root www-data 0 Oct 15 08:36 acl-test.phpهمانطور که میبینید بعد از مجوز ها یک + اضافه شده است. که به معنی داشتن دسترسی ACL است.برای به دست آوردن جزئیات بیشتر در مورد دسترسی هایی که با ACL به فایل دادیم دستور زیر را اجرا کنید:sudo getfacl acl-test.phpخروجی دستور بالا:# file: acl-test.php
# owner: root
# group: www-data
user::rwx
user:vagrant:r-x
group::---
mask::r-x
other::---همون طور که می بینید مجوز  user:vagrant:r-x در این لیست اضافه شده است.برای حذف همه ACL ها از فایل مورد نظر دستور زیر را اجرا کنید:sudo setfacl -b acl-test.phpو برای حذف ACL خاص دستور زیر را اجرا کنید:sudo setfacl -x vagrant acl-test.phpتوجه: در دستور بالا بجای vagrant نام کاربری را خواهید نوشت.نکته: ACL فقط برای فایل ها نیست بلکه می‌توانید برای پوشه‌ها هم استفاده کنید.</description>
                <category>Majid Ganji</category>
                <author>Majid Ganji</author>
                <pubDate>Fri, 15 Oct 2021 14:54:58 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش UFW |‌ فایروال لینوکس</title>
                <link>https://virgool.io/@majidganji1996/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-ufw-%D9%81%D8%A7%DB%8C%D8%B1%D9%88%D8%A7%D9%84-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-vahifmovhfzh</link>
                <description>یکی از مهمترین ابزار ها در سرور فایروال است. اگر بصورت ساده توضیح بدم فایروال برای چه کاری هستش باید بگم  فایروال برای امنیت شبکه هستش که با کنترل درخواست های ورودی و خروجی سرور از دسترسی غیرمجاز به یک پورت خاص جلوگیری میکنه یا از دسترسی یک نرمافزار خاص که داخل سرور در حال اجرا هستش به اینترنت جوگیری میکنه!  لینوکس فایروال های قدرتمندی مانند firewalld و iptable داره. ufw که برنامه یا پوسته ای است که از iptable استفاده میکنه تا کار رو آسون تر کنه چون iptable کمی سخت تره.ما با استفاده از UFW به راحتی میتوانیم تعداد درخواست های ssh رو محدود یا یک رنج از ip رو مسدود کنیم و یا میتونیم اجازه دسترسی به پورت ها رو به یه ip بدهیم یا نزاریم کسی به این پورت ها دسترسی داشته باشد.نصب UFWبرای نصب UFW یکی از دستورات زیر رو بر اساس توزیع خودتون اجرا کنید.sudo apt install ufw
sudo dnf install ufwریست کردن UFWبرای اینکه تمامی قوانین رو حذف کنیم ما میتونیم از دستور زیر استفاده کنیمsudo ufw resetنکته: باید با دسترسی root دستورات UFW را اجرا کنید.بعد از reset کردن UFW  غیر فعال میشود برای فعال شدن دستور زیر رو اجرا کنیدsudo ufw enableو اگر بخواهیم دوباره غیر فعال کنیمsudo ufw disableاگر بخواهیم ببینیم وضعیت UFW چطوری است یعنی چه rule هایی تعریف شده یا UFW فعال است یا خیرsudo ufw statusتنظیمات پیش فرضدر شروع کار با UFW بهتره ما جلو تمام درخواست هایی که به سرور میاد رو بگیریم و تمام درخواست هایی که از سرور ارسال میشه رو آزاد کنیمsudo ufw default deny incoming
sudo ufw default allow outgoingو برای دسترسی به پورت های سرور خودمون با تعریف rule ها این اجازه رو بدیم.بازکردن و بستن پورت هابرای باز کردن پورت  80 از دستورات زیر استفاده می کنیمsudo ufw allow http یاsudo ufw allow 80و اگر بخواهیم پورت ۴۴۳ رو باز کنیمsudo udw allow 443 
یا
sudo ufw allow httpsخب اگر الان بخواهیم پورت ssh رو باز کنیم چه دستوری وارد کنیم؟ بله درستهsudo ufw allow ssh 
یا 
sudo ufw allow 22اگر بخواهیم دسترسی به پورت mysql رو ببندیمsudo ufw deny mysql
یا
sudo ufw deny 3306البته در نظر داشته باشین به طور پیش فرض همه پورت های سرور رو از بیرون بستیم و این فقط مثال هستش.برای باز کردن رنج IP از ۵۰۰۰ تا ۵۰۰۵ از دستور زیر استفاده میکنیمsudo ufw allow 5000:5005/tcp
sudo ufw allow 5000:5005/udpو برای بستن رنج IP از ۶۰۰۰ تا ۶۰۰۶ از دستور زیر استفاده میکنیمsudo ufw deny 6000:6005/tcp
sudo ufw deny 6000:6005/udpبرای باز و بستن رنج IP باید نوع پروتکل TCP یا UDP رو مشخص کنیم وگرنه خطا خواهد داد.با استفاده از limit ما میتوانیم تعداد درخواست به پورت خاص را محدود کنیمsudo  ufw limit sshباز کردن پورت mysql برای یک Ip خاصsudo ufw allow from 192.168.1.5 to any port mysqlو اگر بخواهیم به طور مثال پورت ۸۰۰۰ رو برای شبکه محلی باز کنیم از دستور زیر استفاده می کنیمsudo  ufw allow from 192.168.1.0/24 to any port 8000و برای بستن ssh برای یک ip خاصsudo ufw deny from 192.168.1.1 to any port sshفعال و غیر فعال کردن IPV6همون طور که میبینید در تصویر وقتی به طور مثال پورت ۸۰ رو باز میکنیم یا میبندیم برای ip ورژن ۶ هم همین اتفاق می افته.برای اینکه این ویژگی رو فعال یا غیر فعال کنیم.باید در فایل /etc/default/ufw  مقدار IPV6 برابر yes باشد فعال و اگر برابر no باشد غیر فعال میشودIPV6=yesبهتر است این ویژگی فعال باشد و اگر غیر فعال بود خودتان فعالش کنید.حذف rule هابرای حذف یک رول ۲ حالت وجود دارد راه اول استفاده از شماره rule هستش. که شماره rule رو میتونیم با استفاده از دستور زیر استفاده میکنیمsudo ufw status numberedو الان برای مثال من میخوام دسترسی به پورت mysql رو حذف کنم:sudo ufw delete 5یا میتونم دستوری که برای اضافه کردن rule وارد کرده بودم رو جلو delete بنویسم، مثلا میخوام دسترسی به پورت 8000 که بالاتر نوشتیم رو حذف کنیمsudo ufw delete allow from 192.168.1.0/24 to any port 8000یا محدودیت درخواست ssh رو حذف کنیمsudo ufw delete limit sshو تمام :)</description>
                <category>Majid Ganji</category>
                <author>Majid Ganji</author>
                <pubDate>Sun, 17 May 2020 22:26:24 +0430</pubDate>
            </item>
                    <item>
                <title>مقدمه ای بر  supervisor :)</title>
                <link>https://virgool.io/@majidganji1996/%D9%85%D9%82%D8%AF%D9%85%D9%87-%D8%A7%DB%8C-%D8%A8%D8%B1-supervisor-xfoxhcozg6sf</link>
                <description>گاهی وقت‌ها نیازه هستش تا ما برنامه یا اسکریپتی رو برای همیشه در سرور اجرا کنیم. یعنی بعد از بستن صفحه ترمینال برنامه متوقف نشه، یا اگر برنامه خطا داشته باشه و متوقف بشه یا سرور ریستارت بشه برنامه دوباره به صورت اتوماتیک اجرا بشه.برای این که با supervisor کار کنیم به یک اسکریپت یا برنامه نیاز داریم. من برای این کار یک برنامه کوچک با golang نوشتم که  روی پورت ۵۰۰۰ اجرا میشه.package main

import (
	&amp;quoterrors&amp;quot
	&amp;quotfmt&amp;quot
	&amp;quotlog&amp;quot
	&amp;quotnet/http&amp;quot
	&amp;quotos&amp;quot
)

func main() {
	http.HandleFunc(&amp;quot/&amp;quot, func(w http.ResponseWriter, r *http.Request) {
		fmt.Println(&amp;quotNew Request!&amp;quot)
		fmt.Println(&amp;quot---------&gt; &amp;quot, os.Getenv(&amp;quotTEST_ENV&amp;quot))
		fmt.Println(&amp;quot=========&gt; &amp;quot, os.Getenv(&amp;quotTEST_ENV_TWO&amp;quot))
		fmt.Fprintf(w, &amp;quotHello world&amp;quot)
	})

	http.HandleFunc(&amp;quot/error&amp;quot, func(w http.ResponseWriter, r *http.Request) {
		log.Println(errors.New(&amp;quotcan&#039;t divide by zero&amp;quot))
		fmt.Fprintf(w, &amp;quotError :)&amp;quot)
	})

	fmt.Println(&amp;quothttp://localhost:5000&amp;quot)
	http.ListenAndServe(&amp;quot:5000&amp;quot, nil)
}خب حالا باید بریم سراغ نصب supervisorبرای نصب supervisor نسبت به توزیع‌ خودتون یکی از دستورات زیر رو اجرا کنیدsudo apt install supervisor
sudo pacman -Suy supervisor
sudo dnf install supervisorبعد از نصب supervisor باید این سرویس رو با دستور زیر اجرا کنیم.sudo systemctl start supervisordو اگر بخواهیم بعد از از ریستارت سرور supervisor خودش، خود به خود اجرا بشه دستور زیر رو اجرا میکنیم.sudo systemctl enable supervisordتنظیم نحوه اجرای برنامه با supervisorاول باید محل ذخیره تنظیمات رو توی supervisor مشخص کنیم تا supervisor بتونه تنظیمات برنامه رو پیدا کنه برای این کار باید آخر فایل/etc/supervisor/supervisord.confویرایش کنیم و دستورات زیر رو بنویسم یا اصلاح کنیم:[include]
files = /etc/supervisor/conf.d/*.confالان تمامی فایل هایی با پسوند .conf که در مسیر /etc/supervisor/conf.d رو supervisor میتونه پیدا کنه و در مسیر /etc/supervisor/conf.d/ فایلی به اسم test.conf ایجاد میکنیم و موارد زیر رو داخل فایل مینویسیم.[program:test]
command=/home/majid/w/go/src/test-supervisor/server
directory=/home/majid/w/go/src/test-supervisor
autostart=true
autorestart=true
startretries=3
user=majid
environment=TEST_ENV=&#039;test env one&#039;,TEST_ENV_TWO=&#039;test env two&#039;
stderr_logfile=/home/majid/w/go/src/test-supervisor/stderr.log
stdout_logfile=/home/majid/w/go/src/test-supervisor/stdout.logمن محتوای کامل فایل رو بالا گذاشتم تا در اینجا توضحاتشون رو بدم.[program:test]: در این جا نام برنامه را تعریف کردیم که test هستش، توجه کنید که [program:-----] غیر قابل تغییر است و باید بنویسیم.command=/home/majid/w/go/src/test-supervisor/serverبا استفاده از این، دستور اجرایی یا نحوه اجرای برنامه رو مشخص میکنیم. و اگر نیاز باشد ارگومانی به برنامه پاس بدهیم باید اینجا بنویسیم.directory=/home/majid/w/go/src/test-supervisorمحل برنامه رو مشخص میکنیم و supervisor قبل از اجرای برنامه cd میکنه داخل این پوشه.autostart=trueوقتی مقادرش برابر true است یعنی بعد از اجرا supervisor (مثلا بعد از بوت شدن یا ریستارت سرور) برنامه به صورت اتوماتیک اجرا بشهautorestart=trueوقتی برنامه کرش کنه یا به هر دلیلی برنامه متوقف بشه supervisor از اول برنامه را اجرا کنه البته اگر مقدارش true باشد.startretries=3تعداد دفعاتی که بعد از متوقف شدن یا کرش کردن، برنامه را اجرا بشهstderr_logfile=/home/majid/w/go/src/test-supervisor/stderr.logمحل ذخیره سازی خروجی های برنامه مثل print وغیره. البته باید دقت کنید که supervisor نمی تواند پوشه ایجاد کند پس باید تمام پوشه های مسیر را بررسی کنید که وجود داشته باشد.stdout_logfile=/home/majid/w/go/src/test-supervisor/stdout.logخطا های برنامه (مثلا پیامی که در موقع کرش برنامه میده.) در این فایل ذخیره میشود. البته باید دقت کنید که supervisor نمی تواند پوشه ایجاد کند پس باید تمام پوشه های مسیر را بررسی کنید که وجود داشته باشد.user=majidاکانتی که میخواهید برنامه باهاش اجرا شودenvironment=TEST_ENV=&#039;test env one&#039;,TEST_ENV_TWO=&#039;test env two&#039;متغیر های محیطی که برنامه در زمان اجرا نیاز دارد.بعد از ذخیره این فایل برای اینکه supervisor این تنظیمات را بخواند باید دستورات زیر را اجرا کنیم.Sudo supervisorctl reread # خواندن تنظیمات جدید
Sudo supervisorcrl update # اعمال تنظیمات در supervisorحالا اگر بخواهیم ببینیم  چه برنامه هایی توسط supervisor اجرا شده، دستور supervisorctl را اجرا میکنیم.و وارد قسمت کنترل supervisor میشویم. ما میتونیم با دستورstop testبرنامه را متوقف کنیم و با دستورstart testبرنامه رو اجرا کنیم. و اگر بخواهیم از این حالت بیرون بیاییم ctrl + c رو باید بزنیم. و همچنین بیرون از supervisorctl هم میتونیم برنامه را متوقف و اجرا کنیم.sudo supervisorctl stop test
sudo supervisorctl start testبعد از اجرای برنامه localhost:5000 رو باز کنید. میبینیم که برنامه به خوبی در حال اجراست.</description>
                <category>Majid Ganji</category>
                <author>Majid Ganji</author>
                <pubDate>Sun, 03 May 2020 14:04:46 +0430</pubDate>
            </item>
            </channel>
</rss>