Facebook development with PyFacebook and SSH tunnels
I recently started work on a fun little Facebook application and of course wanted to use the Django framework. Although development appears to have pretty much ceased, PyFacebook seems to be the most feature rich of the Python APIs and so I chose to use it. I wanted to develop a FBML canvas application which requires Facebook to be able to talk unhindered to your web server, which can be quite the problem when using your local machine to develop. If you read the tutorial it talks about setting up port forwarding on your router in order to allow access. For me this was not a feasible solution; I don't always have full access to the router I'm behind. I took a leaf from the Rails RFacebook module's solution to the problem and decided to setup a SSH tunnel. Essentially the tunnel utilizes my existing public web server and redirects all traffic for a specified port to my local machine. So you need a public web server you have access to via SSH.
The first step is to make sure SSH on the server is setup to allow tunneling. I use Ubuntu so some of the following steps may differ depending on your distro of choice. Open a terminal and SSH as you normally do to your server, we need to modify the ssh.config:
sudo nano /etc/ssh/sshd_config
There are two options that I needed to add to the configuration:
GatewayPorts yesPermitTunnel yes
The GatewayPorts option allows anyone to be redirected to your local machine, without this option they would need to be logged into the machine; which Facebook can't do. The PermitTunnel option turns the actual tunneling on. Its a good idea to also check your iptables are allowing access to the particular port you want to tunnel. In my case I am tunneling port 8000 directly to my machine so I want to make sure its available.
iptables -L
and you should see something like this:
ACCEPT tcp -- anywhere anywhere tcp dpt:www ACCEPT tcp -- anywhere anywhere tcp dpt:https ACCEPT tcp -- anywhere anywhere tcp dpt:8000
If you don't see the port 8000 in the list, this article should help you get it setup.
Now we we need to configure the Facebook application's callback URL to tell Facebook where it can find the web server (through the tunnel) that will serve the FBML canvas. Login to Facebook and go to your Application Settings page then open the Canvas settings. Modify the Canvas Callback URL field to be
http://www.mydomain.com:8000/directory/
Note the port we're using in this case port 8000 which corresponds to the port opened in our iptables.
The final step is to open the tunnel and run Django development server. Open a terminal on your machine and enter the following command; replacing the values where appropriate.
ssh -v -p 30000 -R 8000:localhost:8000 username@www.mydomain.com
I run my ssh server on a non-default port of 30000. This command translates to open ssh in verbose mode (-v) to port 30000, then open a tunnel (-R) on the remote server using port 8000 and redirect it to my localhost at port 8000 and finally login as me to my server. If the tunnel opens successfully, verbose mode will let us know. If not, check the settings above.
debug1: Authentication succeeded (publickey). debug1: Remote connections from LOCALHOST:8000 forwarded to local address localhost:8000 debug1: channel 0: new [client-session] debug1: Requesting no-more-sessions@openssh.com debug1: Entering interactive session. debug1: remote forward success for: listen 8000, connect localhost:8000 debug1: All remote forwarding requests processed
In your browser open the Facebook application and, as if by magic, you should be getting pages served through the tunnel, verbose mode will print out each connection as its processed.
debug1: connect_next: host localhost ([127.0.0.1]:8000) in progress, fd=7 debug1: channel 1: connected to localhost port 8000 debug1: channel 1: free: 66.220.146.249, nchannels 2
Lovely. If you have any questions or issues, leave them in the comments and I'll do my best to assist.
