GIT sunucusuna çok kullanıcılı erişimin organizasyonu

Git sunucusunu kurarken ve yapılandırırken, birkaç kullanıcının çeşitli projelere erişimini organize etme sorusu ortaya çıkar. Sorunu araştırdım ve tüm gereksinimlerimi karşılayan bir çözüm buldum: basit, güvenli ve güvenilir.

Dileklerim şunlardır:

  • her kullanıcı kendi hesabıyla bağlanır
  • Bir proje üzerinde birden fazla kullanıcı çalışabilir
  • aynı kullanıcı birden fazla projede çalışabilir
  • her kullanıcı yalnızca üzerinde çalıştığı projelere erişebilir
  • Yalnızca bir tür web arayüzü aracılığıyla değil, komut satırı aracılığıyla da bağlanmak mümkün olmalıdır.

Ayrıca harika olurdu:

  • Kontrol eden kişilere salt okunur izinler verin
  • Git'te kullanıcı erişim haklarını kolayca yönetin

GIT sunucusuna erişim için olası seçeneklere genel bakış

Her şeyden önce, ne arasından seçim yapacağınızı bilmeniz gerekir, bu yüzden burada Git protokollerine hızlı bir genel bakış sunacağız.

  • ssh - sunucuya erişmek için özel olarak oluşturulmuş bir kullanıcı hesabı kullanılır.
    • Git'in, tüm depolara erişim için tek bir hesabın kullanımını önerilerinin dışında bırakmaması garip. Bu benim gereksinimlerimi hiç karşılamıyor.
    • Birden fazla hesap kullanabilirsiniz, ancak kullanıcı erişimini yalnızca belirli dizinlerle nasıl sınırlayabilirsiniz?
      • Ana dizine kapanmak uygun değildir çünkü diğer kullanıcılar için oraya yazma erişimini organize etmek zordur.
      • Ana dizininizdeki sembolik bağlantıları kullanmak da zordur çünkü Git bunları bağlantı olarak yorumlamaz
      • Tercümana erişimi kısıtlamak mümkündür ancak her zaman çalışacağına dair tam bir garanti yoktur.
        • Bu tür kullanıcılar için genellikle kendi komut yorumlayıcınızı bağlayabilirsiniz, ancak
          • ilk olarak, bu zaten bir tür zor karar,
          • ve ikincisi, bunun üstesinden gelinebilir.

    Ancak kullanıcının herhangi bir komutu çalıştırabilmesi sorun olmayabilir mi?.. Genel olarak, tam olarak nasıl kullanılacağını anlarsanız bu yöntem göz ardı edilemez. Bu yönteme daha sonra döneceğiz ama şimdilik diğer alternatifleri kısaca ele alacağız, belki daha basit bir şey çıkar.

  • Git yerel protokolü sshfs ile birlikte kullanılabilir, birden fazla kullanıcı kullanılabilir, ancak esasen önceki durumla aynıdır
  • http - salt okunur
  • git salt okunurdur
  • https - kurulumu zor, ek yazılıma ihtiyacınız var, kullanıcı erişimini düzenlemek için bir tür kontrol paneline ihtiyacınız var... mümkün görünüyor, ancak bir şekilde her şey karmaşık.

Git sunucusuna çok kullanıcılı erişimi düzenlemek için ssh protokolünü kullanma

Ssh protokolüne dönelim.

Git için ssh erişimini kullandığınız için sunucu verilerinin güvenliğini sağlamanız gerekir. Ssh aracılığıyla bağlanan kullanıcı, Linux sunucusunda kendi oturum açma bilgilerini kullanır, böylece ssh istemcisi aracılığıyla bağlanıp sunucunun komut satırına erişebilir.
Bu tür erişime karşı tam bir koruma yoktur.

Ancak kullanıcının Linux dosyalarıyla ilgilenmemesi gerekir. Önemli bilgiler yalnızca git deposunda saklanır. Bu nedenle, erişimi komut satırı üzerinden kısıtlamak değil, Linux araçlarını kullanarak kullanıcının katıldığı projeler hariç projeleri görüntülemesini yasaklamak mümkündür.
Açık seçim Linux izin sistemini kullanmaktır.

Daha önce de belirttiğimiz gibi ssh erişimi için yalnızca tek bir hesap kullanmak mümkündür. Bu yapılandırma, önerilen git seçenekleri listesinde yer almasına rağmen birçok kullanıcı için güvenli değildir.

Yazının başında verilen gereklilikleri uygulamak için hakların ve sahiplerin atanmasıyla aşağıdaki dizin yapısı oluşturulur:

1) proje dizinleri

dizin1(proj1:proj1,0770)
dizin2(proj2:proj2,0770)
dizin3(proj3:proj3,0770)
...
nerede
dir1, dir2, dir3 - proje dizinleri: proje 1, proje 2, proje 3.

proj1:proj1, proj2:proj2, proj3:proj3, ilgili proje dizinlerinin sahipleri olarak atanan, özel olarak oluşturulmuş Linux kullanıcılarıdır.

tüm dizinlerin izinleri 0770 olarak ayarlandı; sahibi ve grubu için tam erişim ve diğer herkes için tam yasak.

2) geliştirici hesapları

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

Kilit nokta, geliştiricilere ilgili projenin sistem kullanıcısı sahibinden oluşan ek bir gruba atanmasıdır. Bu, Linux sunucu yöneticisi tarafından tek bir komutla yapılır.

Bu örnekte, "Geliştirici 1" proj1 ve proj2 projeleri üzerinde çalışıyor ve "Geliştirici 2" proj2 ve proj3 projeleri üzerinde çalışıyor.

Geliştiricilerden herhangi birinin komut satırı üzerinden ssh ile bağlanması durumunda, katılmadıkları proje dizinlerinin içeriklerini görüntüleme hakları bile yeterli olmayacaktır. Bunu kendisi değiştiremez.

Bu prensibin temeli Linux haklarının temel güvenliği olduğundan bu şema güvenilirdir. Ayrıca programın yönetimi oldukça kolaydır.

Hadi uygulamaya devam edelim.

Linux sunucusunda Git depoları oluşturma

Kontrol ediyoruz.

[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

Elle yazmaktan yoruldum...

[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

Başkalarının depolarına komut satırından erişmenin ve hatta içeriklerini görüntülemenin imkansız olduğuna inanıyoruz.

[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'te aynı projede birden fazla geliştiriciyle işbirliği yapın

Bir geliştirici yeni bir dosya sunarsa, diğer geliştiriciler onu değiştiremez, çünkü kendisi bu dosyanın sahibidir (örneğin, dev1) ve projenin kullanıcı sahibi değildir (örneğin, proj1). Sunucu taraflı bir repository’ye sahip olduğumuz için öncelikle “.git” dizininin nasıl yapılandırıldığını ve yeni dosyalar oluşturulup oluşturulmadığını bilmemiz gerekiyor.

Yerel Git deposu oluşturma ve Git sunucusuna gönderme

İstemci makinesine geçelim.

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>

Aynı zamanda sunucuda yeni dosyalar oluşturulur ve bunlar push işlemini gerçekleştiren kullanıcıya aittir.

[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]$

Değişiklikleri Git sunucusuna yüklediğinizde ek dosyalar ve dizinler oluşturulur ve bunların sahipleri aslında yüklemeyi yapan kullanıcıdır. Ancak daha sonra bu dosya ve dizinlerden oluşan grup aynı zamanda bu kullanıcının ana grubuna da karşılık gelir, yani dev1 kullanıcısı için dev1 grubu ve dev2 kullanıcısı için dev2 grubu (geliştirici kullanıcısının ana grubunu değiştirmek yardımcı olmaz, çünkü o zaman birden fazla proje üzerinde nasıl çalışabilirsiniz?). Bu durumda, dev2 kullanıcısı, dev1 kullanıcısı tarafından oluşturulan dosyaları değiştiremeyecektir; bu da işlevsellikte bir bozulmaya neden olabilir.

Linux chown - bir dosyanın sahibini normal bir kullanıcı tarafından değiştirmek

Bir dosyanın sahibi, sahipliğini değiştiremez. Ancak kendisine ait olan bir dosyanın grubunu değiştirebilir ve daha sonra bu dosya aynı grupta yer alan diğer kullanıcılar tarafından da değiştirilebilir. İhtiyacımız olan şey bu.

Git kancasını kullanma

Hook'un çalışma dizini projenin kök dizinidir. hook, push işlemini yapan kullanıcının altında çalışan bir yürütülebilir dosyadır. Bunu bilerek planlarımızı uygulayabiliriz.

[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

ya sadece

vi hooks/post-update

İstemci makinesine dönelim.

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 sunucusunda, taahhütten sonra kanca güncelleme sonrası betiğinin çalışmasını kontrol ediyoruz

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

- boş, her şey yolunda.

Git'te ikinci bir geliştiriciye bağlanma

İkinci geliştiricinin çalışmasını simüle edelim.

istemcide

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

Ve aynı zamanda sunucuda...

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

— yine boş, her şey çalışıyor.

Git projesini silme ve projeyi Git sunucusundan indirme

Tüm değişikliklerin kaydedildiğinden bir kez daha emin olabilirsiniz.

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

— bir Git projesini silmek için dizini tamamen temizlemeniz yeterlidir. Bu komutu kullanarak mevcut dizini silmek imkansız olduğundan oluşan hataya katlanalım, ancak bu tam olarak ihtiyacımız olan davranıştır.

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'te erişimi paylaşma

Şimdi ikinci geliştiricinin üzerinde çalışmadığı Proj1 projesine Git üzerinden bile erişemediğinden emin olalım.

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.

Artık erişime izin veriyoruz

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

ve bundan sonra her şey işe yarıyor.

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

Daha fazla bilgi için,

Ayrıca, dosya ve dizin oluştururken varsayılan izinlerle ilgili bir sorun varsa CentOS'ta bu komutu kullanabilirsiniz.

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

Ayrıca makalede küçük yararlı şeylerle karşılaşabilirsiniz:

  • Linux'ta bir dizin ağacı nasıl oluşturulur
  • sed'de belirli bir satırdan dosyanın sonuna kadar bir dizi adres nasıl aktarılır, yani ilk satır hariç tüm satırlarda sed'de değişiklik yapılır
  • Linux bulmada bir arama koşulu nasıl tersine çevrilir
  • Linux kabuğunda tek satırlık bir satır kullanarak birden fazla satırın bir döngüye nasıl geçirileceği
  • Bash'ta tek tırnaklardan nasıl kaçılır
  • Windows komut satırında tüm içeriğiyle birlikte bir dizin nasıl silinir
  • Bir dosyayı yeniden yazmadan yeniden adlandırmak için bash mv nasıl kullanılır?

İlginiz için teşekkür ederiz.

Kaynak: habr.com

Yorum ekle