Thursday, March 23, 2017

How to run arbitrary binary executables on AWS Lambda 6.10+

After posting the hack yesterday, AWS coincidentally released the Node.js 6.10 platform. The old method from 0.10 now works:

1. Create a bin/ directory inside your project directory.
2. Statically compile your binary as much as possible. Put it inside your bin/ directory. Put any shared libraries that it needs inside the bin/ directory too.
3. chmod +x bin/hello-world-binary
4. Do something like:

'use strict';

const exec = require('child_process').exec;

process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/bin';
process.env['LD_LIBRARY_PATH'] = process.env['LAMBDA_TASK_ROOT'] + '/bin';

exports.handler = (event, context, callback) => {
    const cmd = 'hello-world-binary';
    const child = exec(cmd, (error) => {
        callback(error, 'Process complete!');
    });

    child.stdout.on('data', console.log);
    child.stderr.on('data', console.error);
};

5. ZIP your project directory and upload to AWS Lambda. Enjoy!

Wednesday, March 22, 2017

How to run arbitrary binary executables on AWS Lambda 4.3+

I've been enjoying AWS Lambda in my work lately. I appreciate how we can create serverless architecture (or nearly serverless, anyway) on the AWS Platform. Yeah, it's fun to set up Linux and/or FreeBSD servers myself, but oftentimes, this "cloud" thingy makes perfect sense in many scenarios.

Anyway, AWS Lambda has various constraints, such as not being able to install packages yourself. These constraints, according to their documentation, allows them to "perform operational and administrative activities on [our] behalf, including provisioning capacity, monitoring fleet health, applying security patches, deploying [our] code, and monitoring and logging [our] Lambda functions."

OK, fine; but how do you deal with code that depends on an external binary? In previous versions of the Lambda platform (Node.js v0.10), you can do this by statically compiling your binary and by putting it inside the bin/ folder inside your project and, by doing something like:

process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'] + '/bin';
process.env['LD_LIBRARY_PATH'] = process.env['LAMBDA_TASK_ROOT'] + '/bin';

exec('hello-world-binary', function () {});

With the recent update, however, the above code no longer works. On AWS Lambda platform that uses Node.js v4.3+, we'd need to copy all the binaries to the /tmp folder, chmod +x it, and run it from there.

I couldn't find a cleaner solution, so I just wrapped these in a Node.js package:

https://www.npmjs.com/package/lambda_exec

Enjoy!

Monday, December 05, 2016

Disabling WoSign and StartCom from list of trusted CAs

I was setting up an OpenVPN server a while ago. To remove the browser warning on its WebGUI, I used a free certificate from StartSSL because it's more straightforward than Let's Encrypt. As I was setting up the certificate though, I encountered a couple of articles warning the community about StartSSL. You can read more about it here.

Since WoSign and StartCom are no longer trustworthy, I manually removed them from my browsers:





At least the chance of being snooped upon by Chinese state hackers is slightly lessened now.

Monday, November 28, 2016

STARTTLS with Let's Encrypt and PowerMTA

This is an update to my previous post. I tried using the same certificate to let PowerMTA secure our e-mail server using STARTTLS, but unfortunately, Let's Encrypt is still untrusted by our PHP front-end because Let's Encrypt is still a new certificate authority. The solution is to include IdentTrust's root certificate as it's already trusted by all clients.

This setup is specific to a server with Apache and PowerMTA. You can probably make this work without a web server. Simply adjust the paths and other things as necessary.

I'm pasting the previous steps in this post with some updates.

First, log in as root. It's supposed to be a bad practice to work directly on root, but what the heck:

# sudo su -

Then, download GetSSL to your box:

# mkdir -p /root/getssl /etc/letsencrypt

# cd /root/getssl

# curl -s https://raw.githubusercontent.com/srvrco/getssl/master/getssl > getssl

# chmod 700 getssl

Then, generate the default config files:

# ./getssl -c example.org 
Making domain directory - /root/.getssl/example.org 
creating domain config file in /root/.getssl/example.org/getssl.cfg

Edit the global config at: ~/.getssl/getssl.cfg. Pay particular attention to the followine line:
RELOAD_CMD="service httpd reload"

Depending on your system, it can be "service apache2 reload" or something similar. Update as necessary.

Uncomment the following line also:
CA="https://acme-v01.api.letsencrypt.org"

WARNING: The server has a limit of 5 certificates per 7 days, so use the staging server when experimenting. I hit the limit when writing this post. Lolz.

Edit the domain config at ~/.getssl/example.org/getssl.cfg and insert the following lines:

SANS=www.example.org
DOMAIN_KEY_CERT_LOCATION=/etc/letsencrypt/example.org.crt
SERVER_TYPE="https"
CHECK_REMOTE="true"
ACL=('/var/www/pub/.well-known/acme-challenge')
USE_SINGLE_ACL="true"

Adjust the paths as necessary.

The ACL variable above is the path for the Automatic Certificate Management Environment (ACME) challenge. It should point to a folder inside your web server's document root and should be accessible to the public via HTTP. The ACME challenge is used to prove that you control the web server.

Next, edit the Apache config and insert this in your SSL section:

Header always set Strict-Transport-Security "max-age=15768000"
SSLProtocol             all -SSLv2 -SSLv3
SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
SSLHonorCipherOrder     on
SSLCertificateFile /etc/letsencrypt/example.org.crt
SSLCertificateChainFile /etc/letsencrypt/le.crt

Manually download Let's Encrypt's certificate:

# curl -s https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /etc/letsencrypt/le.crt


Next, we need to merge IdenTrust's root certificate with Let's Encrypt's. Open your browser and go to: https://www.identrust.com/certificates/trustid/root-download-x3.html

Then, edit /etc/letsencrypt/le.crt and paste IdenTrust's cert at the bottom of the cert. le.crt should look like:

-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

For convenience, you can also paste the certificate above. Don't do this on sensitive websites though.


Then, execute GetSSL:

./getssl -u -a

Verify if your certificates are OK:

# openssl verify -CAfile /etc/letsencrypt/le.crt /etc/letsencrypt/example.org.crt
/etc/letsencrypt/example.org.crt: OK

Restart Apache:

# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:

Finally, edit your PowerMTA config:

smtp-server-tls-certificate /etc/letsencrypt/example.org.crt
smtp-server-tls-ca-file /etc/letsencrypt/le.crt

<source 0/0>
    allow-starttls yes
    require-starttls-before-auth yes
</source>

Reload PowerMTA:

# service pmta restart
Stopping PowerMTA:                                         [  OK  ]
Starting PowerMTA:                                         [  OK  ]

Let's Encrypt's certificate expires every 90 days, so you need to update your crontab:

# crontab -e

Insert the following line in the crontab:

0 0 1 * * /root/getssl/getssl -u -a

Remember to protect your private keys and set the appropriate permissions. Just leave a comment if I missed some steps.

Thursday, November 24, 2016

Let's Encrypt on RHEL 6.8

It's been almost 3 years since I've last posted in this blog. 2016 is almost over. I think I should make it a point to post regularly.

Anyway, I'd like to share something interesting. There's a certificate authority called Let's Encrypt that gives free certificates through an automated process. According to their website, they have a Python script called Certbot that fetches the certificates and updates your web server's configuration for you.

Usually, I just use StartSSL for project prototypes or paid certificates on production websites, so I'm pretty late on discovering this.

I'm currently tasked on setting up a server here in my work. The goal is to let others send information towards this server and automate the process of setting up PowerMTA configuration based on this information. The most straightforward and relatively secure way to do this is over HTTPS.

Problem: The particular server that I'm working on runs on Red Hat Enterprise Linux 6.8, and Certbot needs updated Python packages to run. After a couple of attempts to solve this, I realized that it's a lost cause so I abandoned it and looked for a more lightweight solution with little dependencies. The best client that I've found so far is GetSSL. It's a straightforward bash script, and I like it!

The server that I'm working on runs on Apache, but I can't find any step-by-step documentation on how to use GetSSL with Apache. Thus, I decided to make one.

First, download GetSSL to your box:

# curl --silent https://raw.githubusercontent.com/srvrco/getssl/master/getssl > getssl

# chmod 700 getssl

Then, generate the default config files:

# ./getssl -c example.org

Making domain directory - /root/.getssl/example.org
creating domain config file in /root/.getssl/example.org/getssl.cfg

Edit the global config at: ~/.getssl/getssl.cfg. Pay particular attention to the following line:

RELOAD_CMD="service httpd reload"


Depending on your system, it can be service apache2 reload or something similar. Update as necessary.

Then, edit the domain config at: ~/.getssl/example.org/getssl.cfg and insert the following lines:



SANS=www.example.org
DOMAIN_CERT_LOCATION="/etc/httpd/getssl/example.org.crt"
DOMAIN_KEY_LOCATION="/etc/httpd/getssl/example.org.key"
DOMAIN_CHAIN_LOCATION="/etc/httpd/getssl/example.org-chain.crt"
CA_CERT_LOCATION="/etc/httpd/getssl/le.crt"
SERVER_TYPE="https"
CHECK_REMOTE="true"
ACL=('/var/www/.well-known/acme-challenge'
     '/var/www/.well-known/acme-challenge')

Adjust the paths as necessary.

The ACL variable above is the path for the Automatic Certificate Management Environment (ACME) challenge. It should point to a folder inside your web server's document root and should be accessible to the public via HTTP. The ACME challenge is used to prove that you control the web server.

Finally, edit the Apache config and insert this in your SSL section:


SSLCertificateFile /etc/httpd/getssl/example.org-chain.crt
SSLCertificateKeyFile /etc/httpd/getssl/example.org.key
SSLCACertificateFile /etc/httpd/getssl/le.crt
Let's Encrypt's certificate expires every 90 days, so you need to update your crontab to automatically renew your certificate:

# crontab -e

Insert the following line in the crontab:

0 0 * * * /path/to/getssl -u -a -q

Save your changes and apply your changes:

service httpd reload

If everything is OK, go back to your global config at ~/.getssl/getssl.cfg and uncomment the following line to use the non-staging server:

CA="https://acme-v01.api.letsencrypt.org"

Then, reload Apache again:

service httpd reload

That's it! Your web server is now running HTTPS. This won't really protect you from being particularly targeted by the NSA (there was a couple of state-sponsored attacks on certificate authorities), but the goal is to make broad mass-surveillance uneconomical. Just leave a comment if I missed some steps. Enjoy, and encrypt all the things!

Tuesday, February 25, 2014

Aws\Ses\SesClient\sendRawEmail() needs base64

Problem: You need to send raw e-mails to Amazon SES using the official PHP AWS-SDK, but Aws\Ses\SesClient\sendRawEmail() doesn't work even though your raw text is correct.

Solution: Encode your data in base64. Had to check their sample Perl script just to discover this. :-/

Working example:
<?php

require 'AWSSDKforPHP/aws.phar';

use Aws\Ses\SesClient;
$client = SesClient::factory(Array(
    'key     => 'foobar',
    'secret' => 'foobarsecret',
    'region' => 'us-east-1'
));


$data =<<EOD
From: "Example" <user@example.org>
To: "Simon Cornelius P. Umacob" <simoncpu@simoncpu.example.org>

hello world!
EOD;


$tmp = $client->sendRawEmail(Array(
    'Source'        => 'user@example.org',
    'Destinations'  => Array('simoncpu@simoncpu.example.org'),
    'RawMessage'    => Array(
        'Data' => base64_encode($data)
    )
));

var_dump($tmp);

?>

Tuesday, February 21, 2012

Kohana nested SELECT statment

Problem
You need to join two tables using a nested SELECT statement.  However, Kohana's Database module doesn't really allow this query:
mysql> select forum_categories.*, (
    ->     select count(forum_data.id)
    ->     from forum_data
    ->     where forum_data.category_id = forum_categories.id and
    ->     forum_data.parent_id = '0'
    -> ) as cat_count
    -> from forum_categories;
+----+----------------+------------------------+-----------+
| id | title          | description            | cat_count |
+----+----------------+------------------------+-----------+
|  1 | Category One   | category 1 description |         2 |
|  2 | Category Two   | category 2 description |         2 |
|  3 | Category Three | category 3 description |         0 |
|  4 | Category Four  | category 4 description |         0 |
|  5 | Category Five  | category 5 description |         1 |
|  6 | Category Six   | category 6 description |         0 |
+----+----------------+------------------------+-----------+
6 rows in set (0.01 sec)

Solution
Rewrite your query as a left outer join (or inner join, depending on your case):
mysql>  select forum_categories.*, ifnull(forum_data.total, 0) as total
    ->   from forum_categories
    ->   left join (
    ->       select category_id, count(forum_data.id) as total
    ->       from forum_data where parent_id = '0'
    ->       group by category_id
    ->   ) as forum_data
    ->   on forum_data.category_id = forum_categories.id;
+----+----------------+------------------------+-------+
| id | title          | description            | total |
+----+----------------+------------------------+-------+
|  1 | Category One   | category 1 description |     2 |
|  2 | Category Two   | category 2 description |     2 |
|  3 | Category Three | category 3 description |     0 |
|  4 | Category Four  | category 4 description |     0 |
|  5 | Category Five  | category 5 description |     1 |
|  6 | Category Six   | category 6 description |     0 |
+----+----------------+------------------------+-------+
6 rows in set (0.01 sec)

Translating to Kohana, we now have:

$subquery = DB::select('category_id', array('COUNT("forum_data.id")', 'total'))
 ->from('forum_data')
 ->where('parent_id', '=', '0')
 ->group_by('category_id');

$query = DB::select('forum_categories.*', array('IFNULL("forum_data.total", 0)', 'total'))
 ->from('forum_categories')
 ->join(array($subquery, 'forum_data'), 'LEFT')
 ->on('forum_data.category_id', '=', 'forum_categories.id')
 ->as_object()
 ->execute();

For more info, check out the Subqueries section of Kohana's Query Builder documentation.

Thursday, October 13, 2011

So long, farewell, and thanks for all the fish!

#include <stdio.h>

int main(void)
{
    printf("Goodbye world... :( \n");

    return 70;
}

Saturday, July 30, 2011

HOWTO Remove the annoying floating ads from Gmail's Preview Theme

Problem
Gmail's Preview Theme without floating ads.
You switched your Gmail theme, and you find the floating advertisement annoying.

Solution (for Chrome)
Modify Gmail's stylesheet to prevent the ads from floating.
  1. Install the Personalized Web Chrome extension.
  2. Go to Tools -> Extensions.
  3. Find the Personalized Web section and click "Options".
  4. Click "Add New Rule".
  5. In the "Match URLs" textbox, input "mail.google.com".
  6. In the "Add CSS" textbox, input:
    .mq {
        position: relative;
        bottom: 0px;
        left: 0px;
        margin: 0px;
    }
  7. Click "Save".
Reload Gmail to see the effect.

FAQ
Q: Why not just disable the advertisement in the first place?
A: Nothing in life is free; Google is providing us with this free service in exchange for displaying ads.  It's a fair deal.

Q: Does this work on Firefox?
A: No, but you can just google for steps on using a custom CSS.  You may use the same CSS from Step 6.

Required packages for building an Android OS on Ubuntu

Problem
You're trying to install the required packages for building a complete Android Operating System from scratch. Upon pasting the commands from the official documentation, you get the following error:

E: Couldn't find package lib32ncurses5-dev
E: Couldn't find package lib32readline5-dev
E: Couldn't find package lib32z-dev
E: Couldn't find package mingw32


Solution
The list of required packages for building an Android OS is wrong. The correct packages are:

sudo apt-get install git-core gnupg flex bison gperf build-essential \
zip curl zlib1g-dev libc6-dev lib64ncurses5-dev \
x11proto-core-dev libx11-dev lib64readline5-dev lib64z-dev \
libgl1-mesa-dev g++-multilib tofrodos


Note: This has been tested on Ubuntu 10.04 (Lucid Lynx). YMMV.

Wednesday, March 16, 2011

Downgrading from PHP 5.3 to 5.2 on Debian Squeeze

Problem

You've installed PHP 5.3 on your Debian Squeeze system. Problem is, some web apps have trouble running on that version. You need to downgrade your system from 5.3 to 5.2.

Solution

Remove the PHP 5.3 packages from your system:
sudo aptitude purge `dpkg -l | grep php| awk '{print $2}' |tr "\n" " "`
Clean the cache just to be sure:
rm -f /var/cache/apt/archives/php5*
Use Karmiс for PHP packages:

echo -e "Package: php5\nPin: release v=karmic\nPin-Priority: 991\n" | sudo tee /etc/apt/preferences.d/php > /dev/null
apt-cache search php5-|grep php5-|awk '{print "Package:", $1,"\nPin: release v=karmic\nPin-Priority: 991\n"}'|sudo tee /etc/apt/preferences.d/php > /dev/null
Add Ubuntu Karmic to source list:

cd /etc/apt/sources.list.d
sudo wget -O karmic.list "http://pastebin.com/download.php?i=q9ya307g"
(Update, October 18, 2012: The sources list has been updated, because Ubuntu no longer supports Karmic. Please leave a comment if this still doesn't work.)

Update the package database:
sudo apt-get update
If the command above produces this error:

W: GPG error: http://security.ubuntu.com karmic-security Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 40976EAF437D05B5
W: GPG error: http://archive.ubuntu.com karmic Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 40976EAF437D05B5
W: GPG error: http://archive.ubuntu.com karmic-updates Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 40976EAF437D05B5
Then import the required keys and add them to your list of trusted keys:

gpg --keyserver hkp://subkeys.pgp.net --recv-keys 40976EAF437D05B5
gpg --export --armor 437D05B5 | sudo apt-key add -

gpg --keyserver hkp://subkeys.pgp.net --recv-keys 40976EAF437D05B5
gpg --export --armor 40976EAF437D05B5 | sudo apt-key add -

gpg --keyserver hkp://subkeys.pgp.net --recv-keys 40976EAF437D05B5
gpg --export --armor 40976EAF437D05B5 | sudo apt-key add -
Finally, install PHP 5.2:
sudo apt-get install -t karmic php5-cli php5-cgi libapache2-mod-php5
UPDATE: Using the Ubuntu sources to download old packages works on Debian. So far, it works on my system, but you may need to use the Debian sources just in case.

Thursday, August 05, 2010

I hate Linux part 2

OK, I was able to run SystemRescueCd's USB creator by running it in Ubuntu Lucid. The USB stick booted, but when I ran GParted, it wasn't able to detect the RAID array.

Linux = FAIL.

The point of this exercise was to run GParted in order to resize our FreeBSD's /usr partition to make way for ZFS. I allocated around ~400GB of space to that partition, but I realized that it's better to use that space for ZFS since I'll be using it for jails.

FreeBSD jails + ZFS = WIN.

I'll just copy /usr to /var, resize it, and move back /usr to the new partition. I hope this works.


(this is probably GParted's fault, but I love to troll hahaha)

Tuesday, August 03, 2010

I hate Linux


Yet another reason why I hate Linux:

SystemRescueCd, a Linux distro designed for administering or repairing a system, doesn't boot and stops with the following error:

!! Cannot find device with /sysrcd.dat. Retrying...

After a bit of googling, it turns out that this occurs because Linux can't detect the USB CD-ROM that was used to boot it. This use case isn't QA'd anymore. Apparently, the solution is to use a USB stick instead.

But what happens if you use a USB stick? It doesn't work:

[root@soulfury mnt]# mount -o loop,exec ~simoncpu/Desktop/systemrescuecd-x86-1.5.8.iso cdrom
[root@soulfury mnt]# cd cdrom
[root@soulfury cdrom]# ls
bootdisk bootprog isolinux ntpasswd sysrcd.dat sysrcd.md5 usb_inst usb_inst.sh usbstick.htm version
[root@soulfury cdrom]# bash usb_inst.sh
No valid USB/Removable device has been detected on your system

I checked the usb_inst.sh source code, and it makes some invalid assumptions on what a USB stick is. Blah. I need to sleep.

Monday, July 26, 2010

FreeBSD: Unable to find device node for dev /dev/ar0s1b in /dev

Problem:
Sysinstall can't continue and stops with the error, "unable to find device node for dev /dev/ar0s1b in /dev".

Solution:
Remove the existing partition table by writing zeros at the start of the disk:
dd if=/dev/zero of=/dev/ar0 bs=64k count=1
(replace as necessary, e.g., ad0)

Saturday, July 17, 2010

Apache: Restricting folders by IP addresses

1st Problem:
You are running an Apache server. You need to restrict access to certain folders by IP addresses.

Solution to 1st problem:
Use .htacess to deny all access to that folder, then allow certain hosts/IP addresses.

AuthName "simoncpu's dark secret"
AuthType Basic

<Limit GET POST>
order deny,allow
deny from all
allow from 10.0.0.
allow from .example.org
allow from this.is.an.example.invalid
</Limit>

2nd Problem:
Your Apache is behind a proxy such as nginx. All requests to your Apache server appear to originate from your proxy.

Solution to 2nd problem:
Install mod_rpaf and restart your web server. .htaccess will now correctly restrict access to your folders.  Refer to its web page for installation instructions.

Sunday, July 04, 2010

Youtube comment hack

As of July 4, 2010, 9:30PM +8GMT, this Youtube comment hack works:
<script>IF_HTML_FUNCTION?<h1><div style="background-color:#00000<wbr>0; position: absolute; top: 0; left: 0; font-size: 100px; color: red">simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu simoncpu  <script>


Update: As of July 5, 2010, 2:40PM +8GMT, this hack no longer works.

Tuesday, April 27, 2010

Hello, Android!

Hello, Android!

Yay, this is my first Android app! Java is really slow especially if you use Eclipse for development.  I tried this on an amd64 machine with 2GB of RAM but this simple app still crawls to a halt.  Anyway, I wish I can try this on a real phone.

Friday, February 19, 2010

Moblin, Eeebuntu 4.0 beta, etc

Just got back from Cebu GNU Linux Users Group meeting. I saw someone using Moblin. Three thumbs up! The UI is very intuitive, and will have no problems with mainstream customer adoption.

Meanwhile, Eeebuntu 4.0 is not even ready for early adopters. The installation stopped somewhere at around 95% and complained about failed GRUB setup. I'm currently downloading Ubuntu 9.10 Netbook Remix because my Eee is left with a broken OS. Let's see how this goes.

Monday, February 08, 2010

FreeBSD on Eee

I've managed to install FreeBSD 8.0 on my Eee. I was planning to install NetBSD 5.0, but I found out that I had to convert the ISO to a memory stick image before I can dd it. For some reasons, unetbootin doesn't work with NetBSD's ISOs. There's a script that converts NetBSD ISOs to memstick images, but it seems that it only works on an existing *BSD system. I could have just SSH'd into a remote NetBSD system so that I can run the script there, but I realized that the output would be too big. SSH access is a privilege and not a right; abusing it with large file transfers is a big no-no.

I tried to manually create an image using Mac OS X, but I couldn't initialize my USB stick's MBR (i.e., I couldn't boot from the USB). It says that it couldn't find "/usr/standalone/i386/boot0". I searched for it at the Mac OS X' original install discs, but I couldn't find it there either.

It is possible to install NetBSD using Mac OS X, but I was like, FreeBSD is already available as a memstick image from its FTP site. Why not use it? Thus, I downloaded it, dd'd it to my USB stick, and installed it on my Eee. Everything was straightforward.

Straightforward is boring. I'll try to recompile the kernel to see if I can further reduce its boot time (it boots less than 20sec from GRUB to login). I strongly suspect that I'll just reduce its space but not its boot time, but I'll never know until I try. I'll also try to install NetBSD via PXE, once I'm done playing with FreeBSD. I haven't tried doing it yet.

Saturday, February 06, 2010

Eeexperiments

Moblin

I've finally got around installing Moblin. I've copied the image to a USB stick and attempted to boot the OS. The boot process didn't continue though. I got the following error:
/dev/sda does not contain a rootfs
/dev/sdb does not contain a rootfs
/dev/sdc does not contain a rootfs
/dev/sdd does not contain a rootfs
I might try tweaking the kernel configs some time to see if it would work. Meanwhile, I'll just install NetBSD.

Boot Booster

Eee's BootBooster reduced the boot time by skipping the pre-boot sequence. Eeebuntu wasted installed a swap partition when I first installed it, but I never used it because I know that swapping would increase the number of writes to my Eee's SSD. Increasing the number of writes would shorten its life span. Thus, I deleted my swap and installed an EFI partition in its place. Once the BIOS detected the new partition, the BootBooster option magically appeared.

coreboot

A quick googling revealed that coreboot is unsupported on an Eee PC 701. I've also stumbled upon flashrom's source code (Linux bios flasher), and it explicitly stated that Eee PC 701 has been verified to be unsupported. Oh well.