Installiamo un repository git su un server locale con accesso ssh ed http su un server in una intranet per condividere i progetti tra sviluppatori. Abbiamo bisogno di un server con ssh configurato, su cui installeremo git ed apache2. Il server è identificato sulla rete con il nome git-projects.
Configurazione di GIT
Per prima cosa installiamo git sul server:
1 |
# apt install git |
Creiamo l’utente git e la sua homedir che conterrà il repository con tutti i progetti all’interno di /opt/git
1 2 3 |
# useradd -b /opt/ -s /bin/bash -m git # chmod -R o-rwx /opt/git |
Ora prendiamo il controllo del nuovo utente e creiamo la cartella .ssh in cui inseriamo un file authorized_keys vuoto dove inseriremo le chiavi ssh pubbliche di tutti gli utenti che dovranno accedere al repository
1 2 3 4 5 6 7 |
# su - git $ mkdir .ssh $ touch .ssh/authorized_keys $ chmod -R go= ~/.ssh |
Copia delle chiavi pubbliche
Per ogni utente che dovrà avere accesso al repository, dobbiamo copiare il contenuto della chiave pubblica ssh contenuta nel file .ssh/id_rsa.pub nel file .ssh/authorized_keys che abbiamo appena creato. Possiamo farlo in qualunque modo purchè vengano preservati owner e diritti di accesso, ad esempio
1 2 3 4 5 6 |
# su - git $ cat >> .ssh/authorized_keys <<! Chiave SSH pubblica 1 Chiave SSH pubblica 2 ! |
Verifichiamo che tutti gli utenti riescano a collegarsi in ssh al server sull’ utenza git
1 |
$ ssh git@git-projects |
Disabilitiamo l’accesso alla login dell’utente git
Dopo aver verificato che l’utenza è accessibile in ssh, possiamo disabilitarne la login modificandone la shell predefinita che al momento per poter effettuare i test è stata impostata su /bin/bash
1 |
# usermod -s /usr/bin/git-shell git |
Se ora proviamo ad accedere in ssh otteniamo un messaggio di errore
1 2 3 |
# su - git fatal: Interactive git shell is not enabled. hint: ~/git-shell-commands should exist and have read and execute access. |
Da questo momento in poi dovremo lavorare nella cartella /opt/git come root impostando di volta in volta l’ownership delle cartelle e dei file che creeremo
Creazione di un progetto vuoto
Ora che abbiamo l’ambiente git configurato, possiamo creare tutti i progetti che ci servono all’interno del repository. Ogni progetto non è nient’altro che un “bare repository” ovvero un progetto privo della cartella di lavoro che conterrà soltanto i file normalmente presenti nella cartella .git
1 2 3 4 5 6 7 8 9 10 |
# cd /opt/git # mkdir progetto1.git # cd progetto1.git # git --bare init Initialized empty Git repository in /opt/git/progetto1.git/ # chown -R git:git . |
Ora che abbiamo creato lo spazio in cui memorizzare i file del progetto1 possiamo clonarlo in locale oppure popolarlo con un progetto esistente
Cloniamo in locale il progetto vuoto
Cloniamo in locale il progetto1 e popoliamo con alcuni file, eseguiamo la commit e pushiamo le modifiche
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ git clone git@git-projects:progetto1.git Cloning into 'progetto1'... warning: Sembra che tu abbia clonato un repository vuoto. $ cd progetto1 $ touch .gitignore $ cat > readme.md <<! Progetto 1 ========== ! $ git add .gitignore readme.md $ git commit -m "First commit" $ git push |
Se ora entriamo nella cartella /opt/git/progetto1 vediamo che il commit appena pushato è stato ricevuto
1 2 3 4 5 6 7 8 |
# cd /opt/git/progetto1.git # git log commit 91a665a7840280b65df6fed4216db857180b1d52 Author: Xxxx Yyyy <xyxyxy@xxx.yyy> Date: Mon Jun 24 15:54:41 2019 +0200 First commit |
Popoliamo il progetto con uno locale esistente
In alternativa possiamo popolare progetto1 con i file provenienti da un progetto creato in locale. In questo caso dopo aver creato il progetto in locale dobbiamo dire dove si trova il repository remoto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$ mkdir progetto1 $ cd progetto1 $ git init Initialized empty Git repository in ~/progetto1/.git/ $ git remote add origin git@git-projects:progetto1.git $ touch .gitignore $ cat > readme.md <<! Progetto 1 ========== ! $ git add .gitignore readme.md $ git commit -m "Commit 1" $ git push -u origin master Counting objects: 4, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (4/4), 274 bytes | 0 bytes/s, done. Total 4 (delta 0), reused 0 (delta 0) To git-projects:progetto1.git * [new branch] master -> master Branch master set up to track remote branch master from origin. |
Accesso anonimo tramite http
Possiamo dare la possibilità di clonare il nostro progetto in modalità anonima quindi senza bisogno di caricare la chiave pubblica ssh nel file dell’utente git. Quesra modalità è molto comoda nel caso di progetti opensource pubblici.
Andremo quindi ad installare in server apache impostando l’utente www-data nel gruppo git ed impostando la DOcumentRoot su /op/git nel virtualhost
Installiamo apache
1 |
# apt install apache2 |
Creiamo il file virtualhost
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# cat >> /etc/apache2/sites-available/001-git-projects.conf <<! <VirtualHost *:80> ServerName git-projects DocumentRoot /opt/git ErrorLog ${APACHE_LOG_DIR}/git-projects-error.log CustomLog ${APACHE_LOG_DIR}/git-projects-access.log combined <Directory /opt/git> Require all granted </Directory> </VirtualHost> ! |
Abilitiamo il nuovo sito
1 |
# a2ensite 001-git-projects |
Diamo all’utente www-data la possibilità di accedere ai file del gruppo git
1 2 3 4 |
# adduser www-data git Aggiunta dell'utente «www-data» al gruppo «git» ... Aggiunta dell'utente www-data al gruppo git Fatto. |
Ora attiviamo il gancio post-update in tutti i progetti a cui vogliamo dare l’accesso anonimo via http, nel nostro caso progetto1
1 2 |
# cd /opt/git/progetto1.git # mv hooks/post-update.sample hooks/post-update |
Normalmente hooks/post-update.sample ha già i diritti di esecuzione, se non dovesse averli assicuriamoci di fornire questi diritti sul file hooks/post-update. Questo script viene eseguito dopo una modifica del progetto, ad esempio tramite una push che in questo caso può avvenire solo via ssh. Lo script esegue il comando git update-server-info ma fino a che non effettuaremo una push sul progetto non potremo clonare o effettuare pull via http. In alternativa possiamo eseguire il comando all’interno della cartella come root ( o come git se non ne abbiamo disabilitato la login)
1 2 |
# cd /opt/git/progetto1.git # git update-server-info |
Lo script crea due file, se lo abbiamo eseguito come root per ragioni di pulizia diamo a questi file l’ownership all’ utente git
1 2 |
# chown -v git:git info/refs # chown -v git:git objects/info/packs |
Ora possiamo clonare il progetto1 tramite protocollo http
1 2 |
$ git clone http://git-projects/progetto1.git Cloning into 'progetto1'... |
Abilitazione del protocollo https
Creiamo un certificato self signed che installiamo su apache per permettere l’accesso anonimo in https
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# cd /etc/ssl/private # openssl req -x509 -days 365 -nodes -newkey rsa:2048 -keyout apache-git-projects.key -out apache-git-projects.crt Generating a RSA private key ....+++++ ....................................................................................+++++ writing new private key to 'apache-git-projects.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:IT State or Province Name (full name) [Some-State]:Milano Locality Name (eg, city) []:Milano Organization Name (eg, company) [Internet Widgits Pty Ltd]:git-projects Organizational Unit Name (eg, section) []:git-projects Common Name (e.g. server FQDN or YOUR name) []:git-projects Email Address []:admin@git-projects |
Abilitiamo il modulo ssl di apache
1 |
# a2enmod ssl |
Creiamo un virtual host per il sito https che è una copia di quello http con l’aggiunta delle direttive con i certificati
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# cat > /etc/apache2/sites-available/001-git-projects-ssl.conf <<! <VirtualHost *:443> SSLEngine on SSLCertificateFile /etc/ssl/private/apache-git-projects.crt SSLCertificateKeyFile /etc/ssl/private/apache-git-projects.key ServerName git-projects DocumentRoot /opt/git ErrorLog ${APACHE_LOG_DIR}/git-projects-ssl-error.log CustomLog ${APACHE_LOG_DIR}/git-projects-ssl-access.log combined <Directory /opt/git> Require all granted </Directory> </VirtualHost> ! |
Abilitiamo il nuovo sito
1 |
# a2ensite 001-git-projects-ssl |
E riavviamo apache
1 |
# systemctl reload apache2 |
Se tentassimo di clonare il progetto in questo momento otterremmo un errore
1 2 3 |
$ git clone https://git-projects/progetto1.git Cloning into 'progetto1'... fatal: unable to access 'https://git-projects/progetto1.git/': server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none |
Poichè il certificato non è firmato da una CA git si rifiuta di utilizzare il protocollo https, però possiamo dirgli di ignorare il check e proseguire clonando il progetto
1 2 3 4 |
$ git config --global http.sslVerify false $ git clone https://git-projects/progetto1.git Cloning into 'progetto1'... |
Se avessimo creato un repository pubblico su internet con un dominio ed un certificato ssl firmato da una CA, ovviamente non sarebbe necessario configurare git pèer non effettuare il check di autenticità