How to configure remote shared access to a git repository on Ubuntu using SSH keys
Requirements: I have a need to share a git repository on a publicly facing server with our development team who are geographically disparate. The team should not have full root SSH access to the server, and the repository should be private (not publicly accessible).
We would like to use SSH keys for authentication so that the developer does not have to type in their password each time they issue a git command that interacts with the server.
These instructions assume Ubuntu Linux 10.04 and Mac OS X client. The instructions are pretty identical if your local workstation is some flavour of Linux. If you want instructions on how to generate a SSH key on Windows, follow these instructions from github.com, which are listed at the bottom of this post.
Begin on the server in question that we’ll call repository.yourtestserver.com:
#create a group for a repository
create group in webmin (gittestuser)
#create a user for the repository and add it to the group.
#Make sure and create a home directory for that user.
create user in webmin (gittestuser)
#give the group rights to the repository – in our example: gittest
chgrp -R gittestuser /srv/repos/git/gittest chmod -R g+swX /srv/repos/git/gittest
then issue these commands
su gittestuser # switch to the git user cd ~ # change to gittestuser's home directory mkdir .ssh # make the .ssh dir touch .ssh/authorized_keys # create an empty authorized_keys file
On Mac OS X client
#generate your local SSH Public key
cd ~/.ssh ssh-keygen -t rsa -C "david@symetrikdesign-test.com"
# stores it in /.ssh/
cd ~/.ssh
#copy the public key to the .ssh/authorized_keys file for the gittestuser user using
#handy utility called ssh-copy-id
NOTE: You will need to download a copy of the ssh-copy-id script which is not part of Mac OS X for some reason.
#install and set permissions for ssh-copy-id on your local Mac OS X machine
$ sudo curl "http://phildawson.co.uk/ssh-copy-id" -o /usr/bin/ssh-copy-id $ sudo chmod +x /usr/bin/ssh-copy-id
#once you’ve downloaded the ssh-copy-id script, you want to use it to copy your rsa id to the ~/.ssh/authorized_keys file on the server using the following command.
$ /usr/bin/ssh-copy-id gittestuser@repository.yourtestserver.com
#SSH into the server with root and verify that the authorized_keys file has been updated
$ ssh root@repository.gittestserver.com $ less /home/gittestuser/.ssh/authorized_keys
#test ssh access using the gittestuser account and that it is using the SSH key, not requiring a password
$ ssh gittestuser@repository.gittestserver.com
#Once, normal SSH access is enabled change the shell for gittestuser to /usr/lib/git-core/git-shell
#so that the only type of access the user has to the server is git.
#First, find out where the git-shell is located:
$ which git-shell $ which results in "/usr/lib/git-core/git-shell"
#edit passwd file for gittestuser (make sure you are logged in as root if not, use sudo)
$ sudo nano /etc/passwd
#change gittestuser shell from /bin/sh to /usr/lib/git-core/git-shell the following line should look like:
gittestuser:x:1000:100::/home/gittestuser:/usr/lib/git-core/git-shell
I’ve also found that you can change the shell to /usr/lib/git-core/git-shell by editing the user through the webmin interface, which is obviously alot easier.
#Now you can try accessing the server with the shell changed and you should be disconnected.
#The following lines are what you should see when trying to connect via regular shell.
fatal: What do you think I am? A shell?
Connection to repository.gittestserver.com closed.
The reason that you change the shell, is so that your developers can only issue git type commands on the server through SSH access, they don’t get any real SSH access to the server.
#now try to clone the repository from the local Mac OS X machine.
git clone gittestuser@repository.gittestserver.com:/srv/repos/git/gittest/.git
Instructions for Windows that may be helpful to you:
For Windows, the best way to do generate an SSH key is to install Win/msysgit, the instructions for Win/msysgit can be found at github.com
The instructions for generating the key are very similar to Linux, but can be found here.
Prevent your SSH connection from locking up
Have you ever been working on a Terminal shell SSH session, get busy and then went back to the shell to issue some more commands or look at something only to find that the shell window has locked up.
This requires you to close the Terminal window, open a new one and then login to your remote session again.
In a previous post here, I showed you how to create a ~/.ssh/config file.
Simply add these two lines to your ~/.ssh/config file and any SSH connection that you have to a remove server should not lock up.
ServerAliveCountMax 3 ServerAliveInterval 10
Simplifying SSH command to access Amazon EC2 server
If you are like me and you have to push the up arrow in your terminal window each time you need to remember exactly what the command is to access your Amazon EC2 server, here is a time saving SSH configuration trick for you.
example:
$ cd ~/.ec2 $ ssh -i davidskey.pem ubuntu@ec2-69-37-131-80.eu-west-1.compute.amazonaws.com
You can create a config file in your ~/.ssh directory to include your identity file for individual host names.
If your Amazon server has a public DNS entry which points to the long Amazon public DNS name, you can make this even easier.
$ cd ~/.ssh $ ls -al (if you don't find a file called "config" you can create one using the following line) $ touch config $ nano config
Add these lines: (assuming that dev.davidsdomain.com is a CNAME DNS entry which points to ec2-69-37-131-80.eu-west-1.compute.amazonaws.com.
Host dev.davidsdomain.com IdentityFile ~/.ec2/davidskey.pem
Host ec2-69-37-131-80.eu-west-1.compute.amazonaws.com IdentityFile ~/.ec2/davidskey.pem
Now you can SSH to both domain names using only the following. Also note that you do not have to change to the ~/.ec2/ directory to issue the SSH command anymore.
$ ssh ubuntu@dev.davidsdomain.com $ ssh ubuntu@ec2-69-37-131-80.eu-west-1.compute.amazonaws.com
One final note, is that this would work on any host that you use a keyfile to access via SSH. This is of course, not limited to Amazon EC2 server access.
Customizations for a Trac & Git install
I spent 2 days setting up my trac server the way I wanted it. Here’s what I did.
These instructions will help you get going faster than I did. There are a few things that need to be tweaked to get it working, and a couple of modules that will make administration easier.
My setup has the following requirements:
No anonymous/public access, SSL traffic, accountmanager plugin to add and configure users through the trac webadmin interface, and gitplugin for use with a Git repository.
These instructions also assume that you are using a Trac appliance AMI at Amazon Web Services from Turnkey Linux which is built on Ubuntu 10.04.1 JeOS.
Change the hostname through webmin to the fully qualified name that you want to use.
Confirm that both /var/spool/postfix/etc/hosts and /etc/hosts use the hostname.
/var/spool/postfix/etc/hosts didn’t seem to get updated properly and was using “trac” as hostname.
POSTFIX CHANGES
General Options:
Set postfix to use hostname
Internet Hostname of this mail system: Default (provided by this system)
the appliance is configured for “localhost” which causes a SMTP 550 invalid HELO rejection
TRAC PLUGINS:
Installed AccountManagerPlugin
$ easy_install http://trac-hacks.org/svn/accountmanagerplugin/0.11
sub-plugins (assuming the use of htpasswd file for user store)
AccountManagerAdminPage
AccountManager
HTPasswdStore
AccountChangeListener
AccountChangeNotificationAdminPanel
AccountModule
LoginModule
Configure Accounts:
You want to use htpasswd as password store which is located at /etc/trac/htpasswd
$ chgrp www-data /etc/trac $ chown www-data /etc/trac $ chgrp www-data /etc/trac/htpasswd $ chown www-data /etc/trac/htpasswd
In Trac webadmin interface -> Admin/Accounts/Configuration
HTPASSWDSTORE = true (1) filename /etc/trac/htpasswd
DISABLE TRAC’s login so you can use the form based login.
$ nano /var/local/lib/trac/git-/conf/trac.ini
and make sure the following line is in the components section
[components] trac.web.auth.loginmodule = disabled
Comment out Trac’s HTTPD CONF so that Apache does not do the authentication and popup an http dialog.
$ nano /etc/trac/apache.conf
comment out the “Require valid-user” like the example below.
AuthType Basic AuthName "Trac" AuthUserFile /etc/trac/htpasswd # Require valid-user
Installed NoAnonymousAccess Trac Plugin
$ easy_install http://trac-hacks.org/svn/noanonymousplugin/0.11
Installed IniAdminPlugin Trac Plugin
$ easy_install http://trac-hacks.org/svn/iniadminplugin/0.11
Configure Notifications in Trac:
In Trac webadmin interface -> Admin/trac.ini notification tab (or do through the actual trac.ini file)
Set always notify owner: True
Set smtp_from_name (username@host.domain.tld – that you set in previous setep in webmin)
Set smtp_from (username@host.domain.tld – that you set in previous step in webmin)
Configure Apache2 to redirect all traffic from HTTP to SSL (HTTPS)
$ nano /etc/trac/apache.conf
edit the virtual host for port 80 like so that it looks something like:
ServerName hostname.domain.tld Redirect / https://hostname.domain.tld # UseCanonicalName Off # ServerAdmin webmaster@localhost
the hostname.domain.tld is what you set the hostname in previous sections above. All browser requests to HTTP will now automatically be redirected to HTTPS.
You must restart both postfix and apache after making most of the changes above, so if something doesn’t work, try restarting the services. You should do this at the very end anyway.
$ service apache2 restart $ service postfix restart
One final note is that you’ll want to set the user permissions in trac to what ever you prefer. I removed all permissions from anonymous and added all permissions to authenticated users with a few exceptions.
$ trac-admin /var/local/lib/trac/git-permission remove anonymous '*'
The code above is the easy to remove permissions for anonymous.
There is no easy way to add all the permissions to authenticated users however….a little bit of a time consumer.
Hope that helps!
Drupal Custom Breadcrumb visibility PHP code
I needed to show a custom breadcrumb on specific pages by URL.
The nodes in question were of “page” content type.
The URLs of these nodes were like:
/green
/green/page1
/green/page2
/green/page3 and so on.
I only wanted the custom breadcrumb to show up on:
/green/page1
/green/page2
/green/page3
and not on /green
I created a breadcrumb with title “Green” and path “green” and used this PHP code for visibility:
$p= explode('/', $_REQUEST['q']); return ($p[0] == 'green' && $node->nid != 79);
where 79 is the Node ID of the /green page.
I was able to get the desired result!