Private Firefox browsing using cloud

In a restaurant or an airport you might be using a public WiFi network. Even though most web service login procedures are protected with SSL (you can check the “https://” prefix), there are still plenty of websites that do not use HTTPS. So if you need privacy you can apply the procedure below.

Use a cloud instance as a secure SOCKS proxy server

You can use your SSH enabled Cloud instance as a proxy server. You can buy one from LeaseWeb :-). All browser traffic to your Cloud instance will be tunneled in the SSL secured SSH tunnel. To start the socks enabled tunnel you only have to issue the following command:

$ ssh -D 8080 user@cloud_instance

If you do not run Linux, but you run Windows, you can download Putty and run from the command prompt:

C:\Users\m.vanderschee> "c:\Program Files (x86)\PuTTY\putty.exe" -D 8080 user@cloud_instance

Where “cloud_instance” is the hostname or IP address of your cloud instance and “user” is the username on that machine (it is better not to use “root”). You need to go to: Firefox > Preferences > Advanced > Network > Settings… > Manual Proxy. The in the field “SOCKS Host” you enter “localhost” and Port “8080”. You can choose “SOCKS v5”, but do NOT check “Use this proxy server for all protocols”. Press “OK” and you are done.

Proxy your DNS requests

Since you don’t want to leak any information at all about your activity, you should also proxy you DNS requests. You can do this by  opening up “about:config” in Firefox and change the setting “network.proxy.socks_remote_dns” to “true”.

Quickly enable/disable the proxy

If you set your Firefox to use a proxy you might want to easily enable and disable the proxy. The QuickProxy Addon allows this. It shows a small green (proxy on) or red (proxy off) icon in the Add-on bar in the lower right corner of your Firefox window.

Share

Encrypted web projects

If you develop web applications and you want to easily run your applications locally, you might be running Linux on your laptop. This is great until your laptop gets stolen. And while it is never fun when your laptop is stolen, there is one thing that can make it worse: compromised data. Imagine somebody stealing your application source code, database and passwords. Insurance covers the value of your laptop, but not the costs of compromised data (assuming you would be able to put a price tag on that).

Fortunately Ubuntu 12.04 offers home folder encryption during standard installation (Full Disk Encryption requires the alternate installer). But when your home folder is encrypted Apache does not want to serve from your home folder anymore (giving Access Denied errors). If you want to make “ecryptfs” and “apache2” to play along nicely you can change the user Apache is running as. This is as easy as changing “www-data” in the “/etc/apache/envars” file to your username, like this:

#export APACHE_RUN_USER=www-data
#export APACHE_RUN_GROUP=www-data
export APACHE_RUN_USER={PUT YOUR USERNAME HERE}
export APACHE_RUN_GROUP={PUT YOUR GROUPNAME HERE}

It is important to realize that Apache can only serve the content when you are logged in. This is expected and desirable behavior, because the home folder should only be mounted when you are logged in.

Share

Migration to Symfony2 continued

On December 21, 2011 Stefan Koopmanschap wrote an excellent article on this blog titled “Painless (well, less painful) migration to Symfony2.” In his article he explained the advantages of doing a gradual migration. The technical solution that he proposed to make this possible was to “…wrap your old application into your Symfony2 application.” He even provided us the tool (The IngewikkeldWrapperBundle code) to do so.

We were very much inspired by his passionate elucidation and we were fully convinced of the urge to start migrating to Symfony2 as soon as possible. However, he also provided us with a “A word of caution” about 2 things: performance and authentication/authorization. This might get some people worried, but not us: it challenged us to find a solution for those two open issues.

1. Performance

As Stefan Koopmanschap explains, in his solution you “…use two frameworks for all your legacy pages” and “…two frameworks add more overhead than one.” Since our Symfony1 application (the LeaseWeb Self Service Center) is not the fastest you’ve ever seen, some customers are even complaining about it’s speed, this got us a little worried. Losing performance was not really an option, so we had to find a solution.

Symfony 1 & 2 both use a Front Controller architecture (one file handling all requests) we were just looking for seperating traffic between the two front controllers. Stefan proposed to do so using Symfony 2 routing and make it use a fall-back route to handle your legacy URLs. We hereby propose to do it using a .htaccess rewrite. This has virtually no overhead, because every Symfony request gets rewritten by mod_rewrite anyway.

2. Authentication/authorization

He also wrote: “Another issue is sessions.” Further clarifying the problem by stating: “If your application works with authentication and authorization, you’ll now have to work with two different systems that have a different approach to authentication and authorization”. Since our application requires both authentication and authorization we had to come up with a solution here. We decided to move the authentication (login page) to Symfony2 and make Symfony1 “trust” this authentication done by “Symfony2”.

To realize this solution we had to enable Symfony1 to “see” and “understand” the Symfony2 session. First we made sure that both applications use the same name by setting the Symfony2 “framework_session_name” setting in “app/config/config.yml” to “symfony”. Then we reverse engineered the Symfony2 session storage and found that it serializes some PHP object into it. To be able to unserialize those objects we had to register an autoload function in Symfony1 using “spl_autoload_register”

Finally, instructions

To solve the performance problem we installed Symfony2 in the “sf2” directory inside the Symfony1 project (next to “apps”) and we started by changing the lines in our “web/.htaccess” file from:

# redirect to front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

And added these lines above it:

# redirect to new symfony2 front controller
RewriteCond %{REQUEST_FILENAME} !-f
# but only if URL matches one from this list:
RewriteCond %{REQUEST_URI} ^/users/login
# end of list
RewriteRule ^(.*)$ sf2/web/$1 [QSA,L]

To support the Symfony2 authentication and authorization in Symfony1 we created a “Symfony2AuthenticationFilter” class. This filter can be loaded by putting it under “lib/filter” folder in your Symfony1 project and add the following lines in “apps/ssc/config/filters.yml”:

symfony2AuthenticationFilter:
    class: Symfony2AuthenticationFilter

For configuration of the filter we added a few new application settings to “/apps/ssc/config/app.yml”:

all:
    symfony2:
        paths: ['sf2/vendor/symfony/src', 'sf2/src', 'sf2/vendor/bundles', 'sf2/vendor/doctrine-common/lib']
        attribute: '_security_main'

This path setting shows that Symfony2 is located in the “sf2” sub-directory of the Symfony1 project. The attribute reflects the name of the Symfony2 firewall. The code of the Symfony2AuthenticationFilter is this:

function symfony2_autoload ($pClassName)
{
  $sf2Paths = sfConfig::get('app_symfony2_paths');

  foreach ($sf2Paths as $path)
  {
    $path = sfConfig::get('sf_root_dir') . DIRECTORY_SEPARATOR . $path;
    $file = $path . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR ,$pClassName ) . ".php";

    if (file_exists($file))
    {
      include($file);
      break;
    }
  }
}

spl_autoload_register("symfony2_autoload");

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\Role\Role;

class Symfony2AuthenticationFilter extends sfFilter
{
  public function execute($filterChain)
  { // get session data
    $sessionData = null;
    $symfony2Attribute = sfConfig::get('app_symfony2_attribute');
    if (isset($_SESSION['_symfony2']['attributes'][$symfony2Attribute]))
    { $sessionData = unserialize($_SESSION['_symfony2']['attributes'][$symfony2Attribute]);
    }
    // get sf1 username
    if (!$this->getContext()->getUser()->isAuthenticated()) $sf1UserName = false;
    else $sf1UserName = $this->getContext()->getUser()->getUserName();
    // get sf2 username
    if (!$sessionData) $sf2UserName = false;
    else $sf2UserName = $sessionData->getUser()->getUserName();
    // if usernames do not match
    if ($sf1UserName!=$sf2UserName)
    { if ($sf2UserName) // if symfony2 is signed in
      { // signin to symfony1
        $this->getContext()->getUser()->setUserName($sf2UserName);
        $this->getContext()->getUser()->setAuthenticated(true);
        $this->getContext()->getUser()->clearCredentials();
      }
      else // if symfony2 is not signed in
      { // signout from symfony1
        $this->getContext()->getUser()->setUserName(false);
        $this->getContext()->getUser()->setAuthenticated(false);
        $this->getContext()->getUser()->clearCredentials();
        // redirect to current page
        $path = $this->getContext()->getRequest()->getPathInfo();
        $this->getContext()->getController()->redirect($path);
      }
    }
    // and execute next filter
    $filterChain->execute();
  }
}

Update (Jan 22, 2013): You can now find the bundle we created for this on the LeaseWeb Labs on GitHub account and Packagist:

Share