This is my personal preference which may be different from yours. I'm choosing to do the following:
- Let any user within the
gitgroup that is NOT thegituser, full access to do what they wish with the repositories, including rename, delete, and move.- It is possible to only allow the git group to only modify items within the repositories, but I chose not to at this time (its only me anyway). I'll append how to do this at the end at a later time.
- Let the
gituser have only enough access to push/pull repositories, list the repositories, and add their public ssh key togitusers.ssh/authorized_keysdirectory. - Allow only the repo/root/sys admin to place repos in the location to serve them publically.
- Allow only specific repo's to be served publically in a seperate folder.
- Have the shortest url using scp syntax
git@serverip:repo.gitandgit://serverip:repo.git. - Make sure all permissions we set perfectly so from inception of creating the repo, to pushing for the 100th time, no conflicts arise, and people have the least amount of permissions needed.
- Make it easier to administrate the repositories, so accidental
sudo mkdir'saren't needed, screwing permissions and causing chaos. - Im sure theres more
https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server
- Be sure to add SSH keys for users that should be able to push to the repos to
/home/git/.ssh/authorized_keys - Be sure to change the shell of the
gitANDgit-rouser
https://git-scm.com/docs/git-shell.html
-
Enable the git-shell for the
gitandgit-rouser- Get the
git-shelllocation:type git-shell sudo chsh git -s /usr/bin/git-shellsudo chsh git-ro -s /usr/bin/git-shell
- Get the
-
Create a
git-shell-commandsdirectory in bothgitandgit-rohome directories (unless shell disabled for git-ro) -
Place a
helpfile inside thegit-shell-commandsdirectory displaying any info you wish -
I've created sample templates of a
helpandlsfile HERE (link to be provided)
help: When run interactively, git-shell will automatically run 'help' on startup, provided it exists.
If a ~/git-shell-commands directory is present, git shell will also handle other, custom commands by running git-shell-commands/<command> <arguments> from the user’s home directory.
If a no-interactive-login command exists, then it is run and the interactive shell is aborted.
https://git-scm.com/book/en/v2/Git-on-the-Server-Git-Daemon
- Run git daemon as
git-rouser - Be sure
git-daemon-export-okis in the repos you wish to servecd /home/git/myrepo.git && touch git-daemon-export-ok
http://serverfault.com/questions/26954/how-do-i-share-a-git-repository-with-multiple-users-on-a-machine#27040
http://stackoverflow.com/questions/4832346/how-to-use-group-file-permissions-correctly-on-a-git-repository#4832402
#### Single/git User Permissions
Change the /home/git directory to rwx rws rx (or rwx rs rx, depending on your permission preference)
sudo chmod 2775 /home/git- Note how we aren't doing it recursively
- With this method, you will need to set
StrictModesin your/etc/ssh/sshd_configfile tono- If your home directory is writable by group, you cannot use pub key to access it (pw auth still fine)
- People consider this bad practice, use at your own risk (if you chose rwx rs rx, you should be fine with
yes
You can change the ownership of the /home/git directory if you wish, it will be needed if you wish to do rwx rs rx, as you won't be able to create new repositories without ownership or sudo
sudo chown $USER:git /home/git
Create the repository
mkdir /home/git/repo.git- Note with our
gidbit, it will havegitgroup permissions, exactly what we want
- Note with our
Init a bare repo with the shared flag
cd /home/git/repo.git && git --bare init --shared- This sets a few things that help administer a remote repo
- It will auto set the
gidbit on any new dirs (we already did that), and deny fast forward pushes
If you're planning on configuring a lot of repositories, it'll be easier to set --shared on all new repos by default.
sudo git config --global core.sharedRepository group(Im not sure if sudo is needed to be honest, shouldn't be)- With this, you can omit the
--sharedflag, as it will now be the default
- With this, you can omit the
- Best to have a public vs private location
- All repos in
/home/gitwhile read-only/git://repos in/opt/git
- All repos in
- Link repos intended for public use/download into the folder the git daemon is serving from
sudo mkdir /opt/git && sudo chown $USER:git /opt/git && sudo chmod 755 /opt/gitcd /opt/git && ln -s /home/git/reponame.git- Ownership of links doesn't matter, obeys the linked folder's permissions
- Again, have the
git-daemon-export-okblank file in the repos you want to serve over thegit://protocol
This ensures only the main (or root) user can move or rename the repos, while still allowing anyone from git group to view/copy/clone/push/pull to the repo.
At the same time, anyone copying from the git:// protocol, only has clone/pull access, and can only view those served from the /opt/git folder, with the git-daemon-export-ok file inside it (which has to be placed via main/root user).
Open port 9418 to allow the git:// protocol through
If using ufw:
sudo ufw allow to any port 9418 proto tcp
It still contains useful info, but with more research comes more precautions etc, and should be used at your own risk.
Its also worthy to note, placing repos in the git user's home directory allows repos to be cloned with git@gitserverip:repo.git which is extremely convenient, so I would advise placing your repos there.
If supporting multiple users and depending on the level of access you are providing (git-shell vs bash for example) you have several options
-
Have (trusted) users, use the
gituser to view/clone/push/pull to the main repo. -
Placing them into the
gitgroup over having them use thegituser and giving themgit-shellaccess.- You can create custom commands to run in their
~/git-shell-commandsdirectory. A few good ones would be:lsto list themcloneto clone the repo into their home directoy, giving them a seperate remote copy (forking, if you will)linkin order to link their's directly to the main repo.
cloneorlinkallows them to useuser@gitserverip:repo.gitinstead ofuser@gitserverip:/home/git/repo.git.
- You can create custom commands to run in their
- Do not add them to the
gitgroup and give themgit-shellaccess. Create custom commands to run in their~/git-shell-commandsdirectory. One beinglsand the otherclone, allowing them a remote copy (fork), but unable to push to the "main" repo.
- Placing them into the
gitgroup over having them use thegituser and giving thembashaccess. They'll be able to freely navigate and copy/link the repos into their home folder however they choose, but unable to rename, move, or change "key" files in the main repo (they can still mess it up by going inside and removing random writable files deeper inside).
For the git user,
- Push/Pull using
git@gitserverip:repo.gitorssh://git@gitserverip:/repo.git
For the users part of the git group
- Again, review http://stackoverflow.com/questions/4832346/how-to-use-group-file-permissions-correctly-on-a-git-repository#4832402 for allowing multiple users with the shared
gitgroup. - Push/Pull using
user@gitserverip:/home/git/repo.gitorssh://user@gitserverip:/home/git/repo.git - If cloned (forked) or linked
- Push/Pull using
user@gitserverip:repo.gitorssh://user@gitserverip:/repo.git
- Push/Pull using
For repos in the folder the git daemon is running from, you should now be able to:
- Pull using
git://gitserverip:/repo.git
Push access is full access to the repo, no pull requests/restrictions of any sort.
Repo permissions (who can push/pull to master, branch, etc) is a whole other thing, possibly even outside of git altogether. That will hopefully be something for another day.
Leave a comment if this helped!
================================================================ My notes:
-
Create
gituser and add self togitgroup -
Set
gituser's shell togit-shelland add a few commands -
Permissions on
git's home dir2775- Note: You MUST set
StrictModes noin your/etc/ssh/sshd_configor pubkey auth won't work due to group writable permissions - Try to use a MatchBlock so only the
gituser's directory can be as such
- Note: You MUST set
-
Permissions on
.ssh700 -
Permissions on
.ssh/authorized_keys600 -
Init remote repo with
git --bare init --shared- Or set it globally
sudo git config --global core.sharedRepository group
- Or set it globally
-
Init local repo and push to origin url
-
Either re-set up all repos this way (preferred) or change current repos using http://stackoverflow.com/questions/4832346/how-to-use-group-file-permissions-correctly-on-a-git-repository#4832402
chgrp -R GROUP /path/to/repo
find /path/to/repo -type d -print0 | xargs -0 chmod g+s
For single/git user configuration (strictly push/pull access to repos on remote server)
-
Change ownership of repos to: $USER:git
sudo chown $USER:git -R /home/git/reponame.git
-
Change mods of repos to: Owner RWX, Group RWX, ALL R_X
sudo chmod 775 -R /home/git/reponame.git
If you're going to be having multiple users using the remote server for things other then strictly git access, here are some things to do to keep your repos safe.
-
Do not allow the user to move/rename the repo
- Place repos into the
/home/gitdirectory which by default, does not allow you to write to it - Or place your repos into a directory that has the following permissions
sudo chown $USER:git -R /folder/containing/repossudo chmod 755 -R /folder/containing/repos
- Place repos into the
-
Do not allow the user to change the configuration of the repo
sudo chmod 755 /home/git/repo.git