This is my personal preference which may be different from yours. I'm choosing to do the following:
- Let any user within the
git
group that is NOT thegit
user, 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
git
user have only enough access to push/pull repositories, list the repositories, and add their public ssh key togit
users.ssh/authorized_keys
directory. - 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.git
andgit://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's
aren'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
git
ANDgit-ro
user
https://git-scm.com/docs/git-shell.html
-
Enable the git-shell for the
git
andgit-ro
user- Get the
git-shell
location:type git-shell
sudo chsh git -s /usr/bin/git-shell
sudo chsh git-ro -s /usr/bin/git-shell
- Get the
-
Create a
git-shell-commands
directory in bothgit
andgit-ro
home directories (unless shell disabled for git-ro) -
Place a
help
file inside thegit-shell-commands
directory displaying any info you wish -
I've created sample templates of a
help
andls
file 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-ro
user - Be sure
git-daemon-export-ok
is 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
StrictModes
in your/etc/ssh/sshd_config
file 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
gid
bit, it will havegit
group 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
gid
bit 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
--shared
flag, 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/git
while 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/git
cd /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-ok
blank 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
git
user to view/clone/push/pull to the main repo. -
Placing them into the
git
group over having them use thegit
user and giving themgit-shell
access.- You can create custom commands to run in their
~/git-shell-commands
directory. A few good ones would be:ls
to list themclone
to clone the repo into their home directoy, giving them a seperate remote copy (forking, if you will)link
in order to link their's directly to the main repo.
clone
orlink
allows them to useuser@gitserverip:repo.git
instead ofuser@gitserverip:/home/git/repo.git
.
- You can create custom commands to run in their
- Do not add them to the
git
group and give themgit-shell
access. Create custom commands to run in their~/git-shell-commands
directory. One beingls
and the otherclone
, allowing them a remote copy (fork), but unable to push to the "main" repo.
- Placing them into the
git
group over having them use thegit
user and giving thembash
access. 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.git
orssh://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
git
group. - Push/Pull using
user@gitserverip:/home/git/repo.git
orssh://user@gitserverip:/home/git/repo.git
- If cloned (forked) or linked
- Push/Pull using
user@gitserverip:repo.git
orssh://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
git
user and add self togit
group -
Set
git
user's shell togit-shell
and add a few commands -
Permissions on
git
's home dir2775
- Note: You MUST set
StrictModes no
in your/etc/ssh/sshd_config
or pubkey auth won't work due to group writable permissions - Try to use a MatchBlock so only the
git
user's directory can be as such
- Note: You MUST set
-
Permissions on
.ssh
700
-
Permissions on
.ssh/authorized_keys
600
-
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/git
directory 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/repos
sudo 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