OS X Mavericks: restoring my development enviromment

I upgraded to OS X Mavericks last night. It’s great, my Mac is faster, and I’ve not touched a single byte of swap yet, even with a ton of stuff open. But like any OS upgrade, there are some things that are causing my dev environment to work strangely. Here’s how I’m fixing them.

Apache just shows 403 Forbidden for all my sites in ~/Sites

This one’s an easy fix. Open /etc/apache/httpd.conf in your favourite editor. Find <Directory "/Library/WebServer/Documents/"> on line 197 and replace it with <Directory "/Users/your-unix-username/Sites/">.

Alternative solution: If you have multiple users on the same Mac all needing ~/Sites to work, you may need to replace the Directory directive entirely with a <DirectoryMatch "/Users/*/Sites/">, but don’t forget to change out the closing </Directory> for a </DirectoryMatch> too.

Once you’ve made your edits, save the file, and run sudo apachectl restart to make apache pick up the config change.

Git shell integration stopped working

I added these lines to my .bash_profile to get RVM info and Git info in my shell prompt:

# Show RVM gemset and Git branch in Bash prompt
source /usr/share/git-core/git-prompt.sh
export PS1="\h:\W \u\[\033[01;34m\]\$(~/.rvm/bin/rvm-prompt g)\[\033[00;33m\]\$(__git_ps1 \"(%s)\")\[\033[00m\]\$ "

Now, however, my shell prompt is a bit broken and has an error above each prompt, like this:

-bash: __git_ps1: command not found
piro:~ my-unix-username$

Turns out I don’t have a

/usr/share/git-core/git-prompt.sh

file anymore, which is causing the __git_ps1 environment variable to not get set.

But, there does appear to be a copy at /Applications/Xcode.app/Contents/Developer/usr/share/git-core/git-prompt.sh so I edited my .bash_profile to and updated the source line with the new path. Not sure it’s such a great idea running it from the /Applications/Xcode.app path but it’s probably better than copying/symlinking it to /usr/share until I get familiar with The New Way Of Doing Things™.

X11 was no longer installed

Easily fixed, just need to download a fresh copy from http://xquartz.macosforge.org.

More issues will be posted here as I find/solve them.

shareit: Simple FTP-based file sharing from the command line

File sharing websites tend to have ads everywhere, and long running HTTP uploads of large files can be a pain in the backside, so I stopped using them a while back. Whenever I needed to share a file with someone, I’d figure out the file’s MD5 sum (to avoid naming collisions), fire up Transmit (the nicest Mac FTP app by far), upload the file, rename it after uploading, then manually type the link and copy/paste the MD5’d filename in and send it to whoever I wanted to share the file with.

It was nice because I hosted the files, and didn’t have to worry about my recipient seeing a bunch of ads or the file sharing service going down (or being taken down). But it had a huge downside in that it wasn’t straightforward. I was doing a whole bunch of the work by hand every time I wanted to share a file with someone, which as a coder seems like I’m doing something wrong. Eventually I got round to automating it, and now it’s much easier to share a file with someone quickly, just fire one line into the terminal and you’re done.

Getting Started
Before you get started, you’ll want to create a simple YAML file called .shareit in your home directory with your FTP config details, like this:

hostname: ftp.yourwebsite.tld
username: yourusernamegoeshere
password: yourpasswordgoeshere
path: public_html/shareit/
http_prefix: http://yourwebsite.tld/shareit/

path should exist on the FTP server, and http_prefix should be the URL that the folder is accessible at. Both path andhttp_prefix should also include the trailing slash.

Note that the URLs shareit generates are not secure, but they are random enough that people won’t be able to guess them easily unless they know the file’s exact contents. It is recommended that you disable your webserver’s automatic directory indexing for the folder you define in http_prefix — if you don’t, people will be able to browse your entire collection of shared files.

Once you’ve set up your config file, make shareit available in your PATH by adding a symlink in /usr/bin or /usr/local/bin or something.

Usage
Using shareit is simple, all you need to do is tell it what file to upload:

$ shareit 10mb.txt
Uploading to http://yourwebsite.tld/shareit/596c35b949baf46b721744a13f76a258.txt: 10000K of 10000K (100%)
Upload complete!

You can download shareit from https://github.com/arussell/shareit.

Lock down SFTP without restricting SSH on Ubuntu 8.10 (Intrepid Ibex)

If you’re running a Linux, Mac OS X or Unix server of any description, SSH is an invaluable tool when it comes to taking control of the machine while you’re not infront of it.

In the world of web hosting, it’s also brings with it SFTP; a fantastic alternative to the very insecure FTP. Except it has one major flaw: by default on Ubuntu (and most Linux distros), one user can see all of another user’s files just by dropping up a directory to /home. Not exactly ideal if you’re providing a shared-hosting service.

So what we want is a chrooted version of SFTP. But this would also chroot SSH too, making it unusable for system administration. So we need to lock down SFTP only, but let SSH run free. We also want to be able to make some users SFTP-only (web hosting customers), and some users SFTP and SSH capable.

Luckily someone known as “The Minstrel”, came up with a pretty good solution to this. Back in November 2007, Mads Madsen also created a guide to this process for Debian/Ubuntu 7.04. This has been my favourite solution for some time now. The OpenSSH project has since created a version of this this idea internally, but annoyingly it’s got a major flaw: wherever you want to chroot the users to must be owned by root. In other words, users will not be able to create any files in the top level of their chroot jail.

Imagine that you have your users data stored in /home/username. You can’t chroot them to /home/username unless you create a directory inside there, and then let them own that. That gives them an ugly chrooted writable path like /htdocs (or whatever you choose to call it), and a / folder they can’t edit. The other option is to chroot them to /home, and let them own their homedir as normal, but then they can see every other user’s files. Again, not ideal.

So I stuck with The Minstrel’s version, but got tired of having to recompile and rebuild all this every time I wanted it on a new machine. Some people would have probably avoided this (actually quite good) solution altogether because it’s a bit too indepth. Well, it just got a bunch easier, because I created all the bits needed and am publishing them here for you to use.

Disclaimer: I make no promises that this won’t electrocute your cat, sleep with your girlfriend, make fun of your children, etc. Infact I make no promises about this at all. That said, for me, this has worked very well several times since Ubuntu 8.10’s release, on a whole variety of machines, and I’ve had no problems with it.

So from your Ubuntu machine, fire up a terminal (or SSH in, if you’re not sat infront of it) and paste this in:

wget http://unadopted.co.uk/openssh/openssh-server_5.1p1-3ubuntu1_i386.deb
sudo dpkg -i openssh-server_5.1p1-3ubuntu1_i386.deb
sudo aptitude hold openssh-server

This will download the modified package, install it, and tell Ubuntu not to replace it with new any of Ubuntu’s versions. Now bear in mind that you won’t get automatic security updates on OpenSSH anymore — you’ll need a new version of this package when OpenSSH 5.2 comes out, but when that comes out, it’ll be a pretty simple copy/paste job to upgrade, just like that was. The Minstrel notes that it’s worth signing up to the openssh-unix-announce mailing list to find out when this is necessary.

Now if this is the first time you’re doing this we need to do a couple extra steps (though you won’t need to do this if you’re just updating):

wget http://unadopted.co.uk/openssh/sftpsh
sudo cp sftpsh /bin/sftpsh
sudo chown root:root /bin/sftpsh
sudo chmod 755 /bin/sftpsh
sudo echo "/bin/sftpsh" >> /etc/shells 

This will download and install a special shell which you’ll need to set up as the login shell for the user accounts for whoever you want to lock down. This will kick them straight out if they try and SSH in, but will still let SFTP work. We also need to tell the system which directory to lock them into by adding a special tag into their home folder definition. Which all sounds a bit more complicated than it really is (it’s just one line to copy and paste).

So, let’s say our web user is called “mywebsite-sftp”. We’d just do this, if we wanted to lock them to their home directory:

sudo usermod -s /bin/sftpsh -d /home/mywebsite-sftp/./ mywebsite-sftp

Simple, right? The Minstrel has built up a pretty good set of FAQs incase you run into any problems.

If you ever change your mind, and want to go back to Ubuntu’s default OpenSSH server and undo all these changes, that’s dead simple too, just copy and paste this in (go-go-gadget uninstaller!):

sudo rm /bin/sftpsh
sudo aptitude remove openssh-server
sudo aptitude install openssh-server 

Warning: If you’re SSH’d in, don’t disconnect between the two aptitude commands, or you won’t have an SSH server to reconnect to (but it will stay alive until you disconnect). Also, you’ll need to remember that the sftpsh shell doesn’t exist anymore, though, and you’ll need to change any users back to a different shell using usermod.

Okay, so that’s that over with. Tell your friends, post it on Facebook, link to this in forum posts, Digg it, link to this from the Ubuntu Wiki, do whatever you feel you must do to share this with the world. :)