سازماندهی دسترسی چند کاربره به سرور GIT

هنگام نصب و پیکربندی یک سرور Git، این سوال در مورد سازماندهی دسترسی چندین کاربر به چندین پروژه مطرح می شود. من کمی در مورد این موضوع تحقیق کردم و راه حلی پیدا کردم که تمام نیازهای من را برآورده می کند: ساده، ایمن، قابل اعتماد.

آرزوهای من این است:

  • هر کاربر با حساب خود ارتباط برقرار می کند
  • چندین کاربر می توانند روی یک پروژه کار کنند
  • یک کاربر می تواند روی چندین پروژه کار کند
  • هر کاربر فقط به پروژه هایی که روی آنها کار می کند دسترسی دارد
  • اتصال باید از طریق خط فرمان امکان پذیر باشد و نه فقط از طریق نوعی رابط وب

همچنین عالی خواهد بود:

  • اعطای حقوق فقط خواندنی به افراد کنترل کننده
  • به راحتی مجوزهای کاربر را در Git مدیریت کنید

مروری بر گزینه های ممکن برای دسترسی به سرور GIT

اول از همه، شما باید بدانید که چه چیزی را انتخاب کنید، بنابراین یک مرور مختصر از پروتکل های Git.

  • ssh - یک حساب کاربری ویژه ایجاد شده برای دسترسی به سرور استفاده می شود.
    • عجیب است که Git استفاده از یک حساب کاربری را برای دسترسی به تمام مخازن توصیه نمی کند. این اصلاً نیازهای من را برآورده نمی کند.
    • شما می توانید از چندین حساب استفاده کنید، اما چگونه می توانید دسترسی کاربر را به دایرکتوری های خاصی محدود کنید؟
      • بستن به فهرست اصلی مناسب نیست، زیرا سازماندهی دسترسی نوشتن برای سایر کاربران در آنجا دشوار است
      • استفاده از پیوندهای نمادین از فهرست اصلی نیز مشکل است زیرا Git آنها را به عنوان پیوند تفسیر نمی کند.
      • دسترسی به مترجم را محدود کنید، خوب، شما می توانید، اما هیچ تضمین کاملی وجود ندارد که این همیشه کار کند
        • شما به طور کلی می توانید مفسر فرمان خود را برای چنین کاربرانی متصل کنید، اما
          • اولا، این یک نوع تصمیم دشوار است،
          • و 2، می توان آن را دور زد.

    اما شاید مشکلی نباشد که کاربر بتواند هر دستوری را اجرا کند؟ .. به طور کلی، اگر دقیقاً نحوه استفاده از آن را بفهمید، نمی توان این روش را رد کرد. ما بعداً به این روش باز خواهیم گشت، اما در حال حاضر به طور خلاصه گزینه های باقی مانده را بررسی خواهیم کرد، شاید چیز ساده تری وجود داشته باشد.

  • پروتکل محلی git را می توان در ترکیب با sshfs استفاده کرد، می توان از چندین کاربر استفاده کرد، اما اساساً مانند مورد قبلی است.
  • http - فقط خواندن
  • git فقط خواندنی است
  • نصب https دشوار است، به نرم افزار اضافی نیاز دارید، نوعی کنترل پنل برای سازماندهی دسترسی کاربر ... به نظر امکان پذیر است، اما به نوعی همه چیز پیچیده است.

استفاده از پروتکل ssh برای سازماندهی دسترسی چند کاربره به سرور Git

بیایید به پروتکل ssh برگردیم.

از آنجایی که دسترسی ssh برای git استفاده می شود، داده های سرور باید ایمن باشند. کاربری که از طریق ssh متصل می شود از لاگین خود در سرور لینوکس استفاده می کند، بنابراین می تواند از طریق کلاینت ssh متصل شود و به خط فرمان سرور دسترسی داشته باشد.
هیچ محافظت کاملی در برابر دستیابی به چنین دسترسی وجود ندارد.

اما کاربر نباید به فایل های لینوکس علاقه مند باشد. اطلاعات معنی دار فقط در مخزن git ذخیره می شود. بنابراین، شما نمی توانید دسترسی را از طریق خط فرمان محدود کنید، اما با استفاده از لینوکس، کاربر را از مشاهده پروژه ها، به استثنای پروژه هایی که در آن شرکت می کند، منع کنید.
استفاده از سیستم مجوز لینوکس واضح است.

همانطور که قبلا ذکر شد، استفاده از تنها یک حساب برای دسترسی ssh امکان پذیر است. این پیکربندی برای چندین کاربر ناامن است، اگرچه در لیست گزینه های git توصیه شده گنجانده شده است.

برای پیاده سازی الزامات ارائه شده در ابتدای مقاله، ساختار دایرکتوری زیر با انتساب حقوق و صاحبان ایجاد می شود:

1) دایرکتوری های پروژه

dir1 (proj1:proj1,0770)
dir2 (proj2:proj2,0770)
dir3 (proj3:proj3,0770)
...
جایی که
dir1، dir2، dir3 - دایرکتوری های پروژه: پروژه 1، پروژه 2، پروژه 3.

proj1:proj1، proj2:proj2، proj3:proj3 کاربران لینوکس مخصوص ایجاد شده هستند که به عنوان مالکان دایرکتوری های پروژه مربوطه منصوب می شوند.

حقوق همه دایرکتوری ها روی 0770 تنظیم شده است - دسترسی کامل برای مالک و گروهش، و ممنوعیت کامل برای بقیه.

2) حساب های توسعه دهنده

Разработчик 1: dev1:dev1,proj1,proj2
Разработчик 2: dev2:dev2,proj2,proj3

نکته کلیدی این است که به توسعه دهندگان گروه دیگری از کاربر سیستم اختصاص داده می شود که مالک پروژه مربوطه است. این کار توسط مدیر سرور لینوکس با یک دستور انجام می شود.

در این مثال، Developer 1 روی پروژه های proj1 و proj2 کار می کند و Developer 2 روی پروژه های proj2 و proj3 کار می کند.

اگر هر یک از توسعه دهندگان از طریق ssh از طریق خط فرمان متصل شوند، حقوق او حتی برای مشاهده محتویات دایرکتوری پروژه هایی که در آن شرکت نمی کند کافی نخواهد بود. خودش نمی تواند آن را تغییر دهد.

از آنجایی که اساس این اصل امنیت اولیه حقوق لینوکس است، این طرح قابل اعتماد است. علاوه بر این، اجرای این طرح بسیار آسان است.

بیایید تمرین کنیم

ایجاد مخازن Git در سرور لینوکس

بررسی می کنیم.

[root@server ~]# cd /var/
[root@server var]# useradd gitowner
[root@server var]# mkdir gitservertest
[root@server var]# chown gitowner:gitowner gitservertest
[root@server var]# adduser proj1
[root@server var]# adduser proj2
[root@server var]# adduser proj3
[root@server var]# adduser dev1
[root@server var]# adduser dev2
[root@server var]# passwd dev1
[root@server var]# passwd dev2

خسته از تایپ کردن...

[root@server gitservertest]# sed "s/ /n/g" <<< "proj1 proj2 proj3" | while read u; do mkdir $u; chown $u:$u $u; chmod 0770 $u; done

[root@server gitservertest]# usermod -aG proj1 dev1
[root@server gitservertest]# usermod -aG proj2 dev1
[root@server gitservertest]# usermod -aG proj2 dev2
[root@server gitservertest]# usermod -aG proj3 dev2

ما متقاعد شده ایم که دسترسی به مخازن دیگران از خط فرمان و حتی مشاهده محتویات آنها غیرممکن است.

[dev1@server ~]$ cd /var/gitservertest/proj3
-bash: cd: /var/gitservertest/proj3: Permission denied
[dev1@server ~]$ ls /var/gitservertest/proj3
ls: cannot open directory /var/gitservertest/proj3: Permission denied

همکاری در Git چند توسعه دهنده در یک پروژه

یک سوال باقی می ماند، اگر یک توسعه دهنده یک فایل جدید را معرفی کند، دیگر توسعه دهندگان نمی توانند آن را تغییر دهند، زیرا او خودش مالک آن است (مثلا dev1) و نه کاربری که مالک پروژه است (مثلا proj1). از آنجایی که ما یک مخزن سرور داریم، اول از همه، باید بدانیم که دایرکتوری “.git” چگونه مرتب شده است و آیا فایل های جدیدی ایجاد می شوند یا خیر.

یک مخزن Git محلی ایجاد کنید و به سرور Git فشار دهید

بیایید به سراغ ماشین مشتری برویم.

Microsoft Windows [Version 6.1.7601]
(c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены.

C:gittest>git init .
Initialized empty Git repository in C:/gittest/.git/

C:gittest>echo "test dev1 to proj2" > test1.txt

C:gittest>git add .

C:gittest>git status
On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   test1.txt

C:gittest>git commit -am "new test file added"
[master (root-commit) a7ac614] new test file added
 1 file changed, 1 insertion(+)
 create mode 100644 test1.txt
 
C:gittest>git remote add origin "ssh://[email protected]/var/gitservertest/proj2"

C:gittest>git push origin master
dev1:[email protected]'s password:
Counting objects: 3, done.
Writing objects: 100% (3/3), 243 bytes | 243.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://10.1.1.11/var/gitservertest/proj2
 * [new branch]      master -> master

C:gittest>

در همان زمان، فایل های جدیدی روی سرور تولید می شوند و متعلق به کاربری است که فشار را انجام داده است

[dev1@server proj2]$ tree
.
├── 1.txt
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── 75
│   │   └── dcd269e04852ce2f683b9eb41ecd6030c8c841
│   ├── a7
│   │   └── ac6148611e69b9a074f59a80f356e1e0c8be67
│   ├── f0
│   │   └── 82ea1186a491cd063925d0c2c4f1c056e32ac3
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

12 directories, 18 files
[dev1@server proj2]$ ls -l objects/75/dcd269e04852ce2f683b9eb41ecd6030c8c841
-r--r--r--. 1 dev1 dev1 54 Jun 20 14:34 objects/75/dcd269e04852ce2f683b9eb41ecd6030c8c841
[dev1@server proj2]$

هنگامی که تغییرات در سرور Git آپلود می شوند، فایل ها و دایرکتوری های اضافی ایجاد می شوند و در واقع متعلق به آپلودکننده هستند. اما گروه این فایل ها و دایرکتوری ها نیز با گروه اصلی این کاربر مطابقت دارد، یعنی گروه dev1 برای کاربر dev1 و گروه dev2 برای کاربر dev2 (تغییر گروه اصلی کاربر توسعه دهنده کمکی نمی کند، زیرا در این صورت چگونه روی چندین پروژه کار کنیم؟). در این حالت، کاربر dev2 نمی تواند فایل های ایجاد شده توسط کاربر dev1 را تغییر دهد و این مملو از نقض عملکرد است.

لینوکس chown - تغییر مالک یک فایل توسط یک کاربر عادی

مالک یک فایل نمی تواند مالکیت آن را تغییر دهد. اما او می تواند گروه فایلی را که متعلق به خودش است تغییر دهد و سپس این فایل توسط کاربران دیگری که در همان گروه هستند قابل تغییر است. این چیزی است که ما نیاز داریم.

با استفاده از Git Hook

دایرکتوری کاری هوک دایرکتوری ریشه پروژه است. hook یک فایل اجرایی است که زیر نظر کاربری که فشار را انجام می دهد اجرا می شود. با دانستن این موضوع می توانیم برنامه های خود را اجرا کنیم.

[dev1@server proj2]$ mv hooks/post-update{.sample,}
[dev1@server proj2]$ sed -i '2,$ s/^/#/' hooks/post-update
[dev1@server proj2]$ cat <<< 'find . -group $(whoami) -exec chgrp proj2 '"'"'{}'"'"' ;' >> hooks/post-update

یا فقط

vi hooks/post-update

بیایید به ماشین مشتری برگردیم.

C:gittest>echo "dev1 3rd line" >> test1.txt

C:gittest>git commit -am "3rd from dev1, testing server hook"
[master b045e22] 3rd from dev1, testing server hook
 1 file changed, 1 insertion(+)

C:gittest>git push origin master
dev1:[email protected]'s password:
   d22c66e..b045e22  master -> master

در سرور Git، کار اسکریپت hook پس از به‌روزرسانی را بعد از commit بررسی کنید

[dev1@server proj2]$ find . ! -group proj2

- خالی، همه چیز خوب است.

اتصال یک توسعه دهنده دوم به Git

بیایید کار توسعه دهنده دوم را شبیه سازی کنیم.

بر روی مشتری

C:gittest>git remote remove origin

C:gittest>git remote add origin "ssh://[email protected]/var/gitservertest/proj2"

C:gittest>echo "!!! dev2 added this" >> test1.txt

C:gittest>echo "!!! dev2 wrote" > test2.txt

C:gittest>git add test2.txt

C:gittest>git commit -am "dev2 added to test1 and created test2"
[master 55d49a6] dev2 added to test1 and created test2
 2 files changed, 2 insertions(+)
 create mode 100644 test2.txt

C:gittest>git push origin master
[email protected]'s password:
   b045e22..55d49a6  master -> master

و در عین حال روی سرور ...

[dev1@server proj2]$ find . ! -group proj2

- دوباره خالی، همه چیز کار می کند.

حذف یک پروژه Git و بارگذاری یک پروژه از یک سرور Git

خوب، می توانید یک بار دیگر مطمئن شوید که همه تغییرات ذخیره شده اند.

C:gittest>rd /S /Q .
Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.

- برای حذف یک پروژه Git، به سادگی دایرکتوری را به طور کامل پاک کنید. بیایید خطای داده شده را تحمل کنیم، زیرا حذف دایرکتوری فعلی با این دستور غیرممکن است، اما این دقیقاً همان رفتاری است که ما نیاز داریم.

C:gittest>dir
 Содержимое папки C:gittest

21.06.2019  08:43    <DIR>          .
21.06.2019  08:43    <DIR>          ..

C:gittest>git clone ssh://[email protected]/var/gitservertest/proj2
Cloning into 'proj2'...
[email protected]'s password:

C:gittest>cd proj2

C:gittestproj2>dir
 Содержимое папки C:gittestproj2

21.06.2019  08:46    <DIR>          .
21.06.2019  08:46    <DIR>          ..
21.06.2019  08:46               114 test1.txt
21.06.2019  08:46                19 test2.txt
C:gittestproj2>type test1.txt
"test dev1 to proj2"
"dev1 added some omre"
"dev1 3rd line"
"!!! dev2 added this"

C:gittestproj2>type test2.txt
"!!! dev2 wrote"

اشتراک گذاری دسترسی در Git

حالا بیایید مطمئن شویم که توسعه دهنده دوم نمی تواند از طریق Git به پروژه Proj1 دسترسی داشته باشد که روی آن کار نمی کند.

C:gittestproj2>git remote remove origin

C:gittestproj2>git remote add origin "ssh://[email protected]/var/gitservertest/proj1"

C:gittestproj2>git push origin master
[email protected]'s password:
fatal: '/var/gitservertest/proj1' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

حالا اجازه دسترسی را بدهید

[root@server ~]# usermod -aG proj1 dev2

و بعد از آن همه چیز کار می کند.

C:gittestproj2>git push origin master
[email protected]'s password:
To ssh://10.1.1.11/var/gitservertest/proj1
 * [new branch]      master -> master

برای اطلاعات بیشتر،

علاوه بر این، اگر هنگام ایجاد فایل ها و دایرکتوری ها در مجوزهای پیش فرض مشکلی وجود داشت، در CentOS می توانید از دستور استفاده کنید

setfacl -Rd -m o::5 -m g::7 /var/gitservertest

همچنین در مقاله می توانید به موارد مفید کوچک برخورد کنید:

  • نحوه ساخت درخت دایرکتوری در لینوکس
  • چگونه می توان طیف وسیعی از آدرس ها را از یک خط خاص به انتهای فایل در sed منتقل کرد، یعنی جایگزینی در sed در تمام خطوط به جز خط اول ایجاد کرد.
  • نحوه معکوس کردن شرایط جستجو در لینوکس Find
  • چگونه چندین خط را از طریق یک لاینر در پوسته لینوکس عبور دهیم
  • چگونه از نقل قول های تک در bash فرار کنیم
  • چگونه یک دایرکتوری را با تمام محتویات در خط فرمان ویندوز حذف کنیم
  • نحوه تغییر نام فایل با استفاده از bash mv بدون بازنویسی

با تشکر از توجه شما.

منبع: www.habr.com

اضافه کردن نظر