- Mastering Puppet(Second Edition)
- Thomas Uphill
- 782字
- 2021-07-16 13:05:25
Git for everyone
At this point, we've shown how to have Git work from one of the worker machines. In a real enterprise solution, the workers will have some sort of shared storage configured or another method of having Puppet code updated automatically. In that scenario, the Git repository wouldn't live on a worker but instead be pushed to a worker. Git has a workflow for this, which uses SSH keys to grant access to the repository. With minor changes to the shown solution, it is possible to have users SSH to a machine as the Git user to make commits.
First, we will have our developer generate an SSH key using the following commands:
[root@client ~]# sudo -iu remotedev [remotedev@client ~]$ ssh-keygen Generating public/private rsa key pair. … Your identification has been saved in /home/remotedev/.ssh/id_rsa. Your public key has been saved in /home/remotedev/.ssh/id_rsa.pub. The key fingerprint is: 18:52:85:e2:d7:cc:4d:b2:00:e1:5e:6b:25:70:ac:d6 remotedev@client.example.com
Then, copy the key into the authorized_keys
file, for the Git user, as shown here:
remotedev@host $ ssh-copy-id -i ~/.ssh/id_rsa git@stand /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys Number of key(s) added: 1
Now try logging into the machine, with ssh 'git@stand'
and then check to make sure that only the key(s) you wanted were added:
[remotedev@client ~]$ ssh -i .ssh/id_rsa git@stand Last login: Sat Sep 26 22:54:05 2015 from client Welcome to Example.com Managed Node: stand Managed by Puppet version 4.2.1
If all is well, you should not be prompted for a password. If you are still being prompted for a password, check the permissions on /var/lib/git
on the stand
machine. The permissions should be 750
on the directory. Another issue may be SELinux security contexts; /var/lib/git
is not a normal home directory location, so the contexts will be incorrect on the git
user's .ssh
directory. A quick way to fix this is to copy the context from the root
user's .ssh
directory, as shown here:
[root@stand git]# chcon -R --reference /root/.ssh .ssh
Note
If you are copying the keys manually, remember that permissions are important here. They must be restrictive for SSH to allow access. SSH requires that ~git
(Git's home directory) should not be group writable, that ~git/.ssh
be 700
, and also that ~git/.ssh/authorized_keys
be no more than 600
. Check in /var/log/secure
for messages from SSH if your remote user cannot SSH successfully as the Git user.
Git also ships with a restricted shell, git-shell
, which can be used to only allow a user to update Git repositories. In our configuration, we will change the git
user's shell to git-shell
using chsh
, as shown here:
[root@stand ~]# chsh -s $(which git-shell) git Changing shell for git. chsh: Warning: "/bin/git-shell" is not listed in /etc/shells. Shell changed.
When a user attempts to connect to our machine as the git
user, they will not be able to log in, as you can see here:
[remotedev@client ~]$ ssh -i .ssh/id_rsa git@stand Last login: Sat Sep 26 23:13:39 2015 from client Welcome to Example.com Managed Node: stand Managed by Puppet version 4.2.1 fatal: Interactive git shell is not enabled. hint: ~/git-shell-commands should exist and have read and execute access. Connection to stand closed.
However, they will succeed if they attempted to use Git commands, as shown here:
[remotedev@client ~]$ git clone git@stand:control.git Cloning into 'control'... remote: Counting objects: 102, done. remote: Compressing objects: 100% (71/71), done. remote: Total 102 (delta 24), reused 0 (delta 0) Receiving objects: 100% (102/102), 9.33 KiB | 0 bytes/s, done. Resolving deltas: 100% (24/24), done.
Now, when a remote user executes a commit, it will run as the git
user. We need to modify our sudoers
file to allow sudo to run remotely. Add the following line at the top of /etc/sudoers.d/sudoers-puppet
(possibly using visudo):
Defaults !requiretty
At this point, our sudo rule for the post-receive
hook will work as expected, but we will lose the restrictiveness of our pre-receive
hook since everything will be running as the git
user. SSH has a solution to this problem, we can set an environment variable in the authorized_keys
file that is the name of our remote user. Edit ~git/.ssh/authorized_keys
, as follows:
environment="USER=remotedev" ssh-rsa AAAA...b remotedev@client.example.com
Finally, edit the pre-receive
hook, by changing the user=$(whoami)
line to user=$USER
.
Now, when we use our SSH key to commit remotely, the environment variable set in the SSH key is used to determine who ran the commit.
Running an enterprise-level Git server is a complex task in itself. The scenario presented here can be used as a road map to develop your solution.