In a project we did recently, we had the requirement to have a private Amazon S3 bucket as an upstream for an nginx server. There is already an existing AWS auth module but it only supports GET requests. So we decided to achieve the same result by doing the signature generation directly via nginx configuration directives. The only things missing were the hmac and base64 methods, which we then implemented it the very useful set-misc-module.
In order to show the details we’ve created a github repository with nginx-examples to share the idea with the community.
happy NGINX coding, the lovely Team …
By default caches uses the field “Cache-Control” to get the TTL for objects they care about. In case of a server side cache the parameter “s-maxage” is responsible for the life time of an object. (see rfc2616). This is fine for almost all cases. The bad thing about this is a bad configured cache proxy also uses this parameter to get it’s caching informations. This causes the backend to have no control to invalidate such an object because it will remain in memory of such a bad configured cache.
So we decided to use a custom field in the http header to tell varnish how long an object should stay in cache. In the backend it was very easy to implement a few lines of code to set the custom field. I called it “Varnish-Control” . The field will contain an integer value which indicates the TTL in seconds. The main part of the work was to configure varnish to use this value instead of s-maxage form the field “Cache-Control”.
In words i did the following:
Once an item was fetched from the backend (so it was not found in the cache) I will set the TTL of the item and stuff it into the cache. Since the field “Varnish-Control” is useless for all request handling nodes on the way to the client i removed the field once the TTL was set.
The first approach was pretty simple:
sub vcl_fetch {
if (obj.http.Varnish-Control) {
set obj.ttl = 7d;
remove obj.http.Varnish-Control;
}
insert;
}
Unfortunately this solution did not care about the value I’ve set into “Varnish-Control” but uses a static value of seven days to cache items. This was not satisfying. So i tried to make it more dynamic. Since it is not possible to assign the value from obj.http.Varnish-Control to obj.ttl i had to use inline C code. This is done by using C{ … }C somewhere in the VCL file.
sub vcl_fetch {
if (obj.http.Varnish-Control) {
C{
char *ttl;
ttl = VRT_GetHdr(sp, HDR_OBJ, "\020Varnish-Control:");
VRT_l_obj_ttl(sp, atoi(ttl));
}C
remove obj.http.Varnish-Control;
}
insert;
}
Finding the right commands to access the header informations and write them into the TTL of the object was PITA. Anyway, I try to explain this two commands:
char *VRT_GetHdr(const struct sess *sp, enum gethdr_e where, const char *n)
void VRT_l_obj_ttl(const struct sess *, double)
Thats it!
All VRT_x commands will be available in this context. This commands can be found in varnish-cache/include/vrt.h and varnish-cache/include/vrt_obj.h
lovely systems is running business critical software and it’s important for us and our customers that the entire system is fully redundant and high available.
in consequent of this we have a 3 steps plan:
load balancing is alread implemented. i’ve written a german howto about it.
hot standby is finishing the last stability tests. again i’ve written two howto’s about drbd and heartbeat.
the backup setup is going productive in the near future. i’m going to write a howto about that in the next few days.
after this steps there shouldn’t be a bottleneck any more.
After some trying it was easy to get openfire running with our official GoDaddy Wildcard SSL Certificate :)
Convert your key and cert to DER format (thanks to AgentBob):
openssl pkcs8 -topk8 -nocrypt -in lovelysystems.com.key -inform PEM -out lovelysystems.key.der -outform DER
openssl x509 -in _.lovelysystems.com.crt -inform PEM -out _.lovelysystems.com.crt.der -outform DER
Get some java utilities to create a java key store (yes java still rosucks, thanks to AgentBob again)
Create a new keystore (/root/keystore.ImportKey):
change the keytool passwords back to the defaults (from ‘importkey’ to ‘changeit’)
Add the GoDaddy Intermediate Certificate:
Move it to openfire (probably back up the old first) and restart openfire
In case of errors:
Howto hide a worpress instance behind a different apache server with the mod_rewrite.
I had the need to move my blog running wordpress 2.0.x to a different server, but keeping the domain name on the “old” server. I tried to do this with mod_rewrite and succeeded only partially :-(
after some hours of hacking around with mod_rewrite and wordpress itself i got i working and want to share my solution:
note: let’s call the origin server SERVER A and the “new” server running wordpress and mySQL SERVER B. SERVER A has only Apache 2 with mod_rewrite running, SERVER B has Apache, mySQL and PHP running.
Step 1: basic rewrite rules on SERVER A
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/blog/.*\.php$
RewriteCond %{REQUEST_URI} !^/blog/wp-.*
RewriteRule ^/blog(.*) http://<SERVER B>/<path to wordpress>/index.php$1 [L,P]
RewriteRule ^/blog$ http://<SERVER B>/<path to wordpress>/ [L,P]
RewriteRule ^/blog(.*)$ http://<SERVER B>/<path to wordpress>$1 [L,P]
note: my blog runs on http://<SERVER A>/blog/
Step 2: configure WordPress
login to wordpress (best done before moving wordpress to SERVER B) and go to the options -> general screen in wordpress admin and set these two values:
WordPress address (URI): http://<SERVER B>/<path to wordpress>
Blog address (URI): http://<SERVER A>/blog
Step 3: hack WordPress
now comes the part that took me hours to figure out. With all the above, wordpress almost worked, but index.php always threw a 404 not found error :-(
The problem was, that Wordpress uses $_SERVER['REQUEST_URI'] to build its links and stuff, but for my setup REQUEST_URI is <path to wordpress on SERVER B>… but this isn’t right, it should be simply /blog/…
this inserted into my config.php file does the trick:
$_SERVER['REQUEST_URI'] = str_replace(’/<path to wordpress on SERVER B>/’, ‘/blog/’, $_SERVER['REQUEST_URI']);
Step 4: there’s no step 4 ;-)
Technorati Tags: mod_rewrite, networking, sysadmin, webdesign
i just found out that my Ubuntu Server 6.10 has login shells for almost all users set in the /etc/passwd file!
That’s a very bad idea because this maybe enabled someone to install “Data Cha0s Back Backdoor” on my machine :-(
I checked this with 2 other fresh Ubuntu Server 6.10 installations and both had the login shells for users like daemon, mail, www-data and so on. Especially www-data should not have a chance to create a shell in my opinion!
So i changed /bin/sh to /usr/sbin/nologin and hope this makes it a bit more secure.
After a collaboration for over 9 years it’s time to say bye bye to our former Hosting Partner Schlund+Partner (now integrated into the 1&1 Internet AG).During the last months their service and availability got worse and worse. The negative highlight was during the last days when parts of their mailsystem went offline once again (http://www.heise.de/newsticker/meldung/83828 and http://www.heise.de/newsticker/meldung/83916).

Lovely Systems is serving several Terrabyte of data per month. The combination of Amazons Elastic Compute Cloud (EC2) and the local datacenter of Telekom Austria in Bregenz is a ideal combination for our hosting services (Telekom Austria Advertisment Video, wmv :)).
1&1: sad, that you perform that bad. Oli, fRiSi, quodt: great, that you work night and day!

I found a web page that showed a few funky characters. It must be an encoding problem so I thought about how to fix this. This is how I did.
First I wanted to know how the template file was encoded. To do that I opened Vim and ran “:set fileencoding”. Vim displayed “latin1″. To make the file utf-8 I ran “:set fileencoding=utf-8″ and saved it. The web page looked ok after that.
To verify the encoding one can use a hex editor. I used khexedit (KDE program) to see what my funny character was in hex. Before I changed the encoding the character was E5 in hex. Python can verify that å should be E5:
>>> u’å’.encode(’latin1′)
‘\xe5′
So the encoding is latin1. To verify that vim changed the file correctly one can check with khexedit after changing the file. khexedit now showed C3 A5 for this character. Checking with python again:
>>> u’å’.encode(’utf-8′)
‘\xc3\xa5′
C3 A5 seems to be correct hex for the å character in utf-8 encoding, so know I can be certain Vim did the right thing.
We successfully deployed our first Zope3 applications on the promising Amazon EC2 cluster. Since my first post in October a lot of things happened. I read a very interesting article about the Jeff Bezo’s Riscy Bet and i’m still convinced that this type of service will be the future of hosting.
Finally I managed to create a Lovely AMI (Amazon Machine Image) based on Ubuntu 6.06.1 LTS to deploy our first application on EC2.
I followed jjc1138 and dougwinter on the AWS (Amazon Webservices) forum and Flex in his development blog.
(more…)
Yay, I got my invitation to use the Amazon Elastic Compute Cloud last week :)
First of all i needed to active the Service, uploaded my X.509 certificate. Congratulations Amazon, that’s the way to do it!
It took me 30 minutes to get a zope instance running :)
After that I downloaded the ec2 tools extracted them to /opt/ec2-api-tools
You’ll need the following environment variables (on OSX):
export EC2_HOME=/opt/ec2-api-tools
export EC2_PRIVATE_KEY=~/.ec2/pk-batlogg.pem
export EC2_CERT=~/.ec2/cert-batlogg.pem
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
export PATH=”$PATH:/opt/ec2-api-tools/bin”
Then create a RSA key pair (i think the call stores the public key at amazon and shows you the private key):
/opt/ec2-api-tools-1.2-5692/bin/ec2-add-keypair lsa001-keypair
I saved it under the name id_rsa-lsa001-keypair
Here we go! Select an instance and start it.
ec2-describe-images shows some images to run:
IMAGE ami-5bae4b32 ec2-public-images/getting-started.manifest 206029621532 available public
IMAGE ami-68ae4b01 ec2-public-images/fedora-core4-base.manifest 206029621532 available public
IMAGE ami-69ae4b00 ec2-public-images/fedora-core4-apache-mysql.manifest 206029621532 available public
IMAGE ami-6dae4b04 ec2-public-images/fedora-core4-apache.manifest 206029621532 available public
IMAGE ami-6fae4b06 ec2-public-images/fedora-core4-mysql.manifest 206029621532 available public
let’s use the fedora-core4-base:
ec2-run-instances ami-5bae4b32 -k lsa001-keypair
after some minutes the machine was up and running:
ec2-describe-instances
RESERVATION r-b0d431d9 538162834475 default
INSTANCE i-c7b357ae ami-5bae4b32 domU-12-31-33-00-04-5D.usma1.compute.amazonaws.com running lsa001-keypair
open the firewall:
/opt/ec2-api-tools-1.2-5692/bin/ec2-authorize default -p 22
/opt/ec2-api-tools-1.2-5692/bin/ec2-authorize default -p 80
/opt/ec2-api-tools-1.2-5692/bin/ec2-authorize default -p 8080
ssh to the virtual host:
ssh -i id_rsa-lsa001-keypair root@domU-12-31-33-00-04-07.usma1.compute.amazonaws.com
that was easy :) now get zope up and running
yum install python
yum install subversion
yum install gcc
yum install python-devel
wget http://apt.ling.li/rpms/python-imaging/python-imaging-1.1.5-1.li.fc4.i586.rpm
yum install tk
rpm -ivh python-imaging-1.1.5-1.li.fc4.i586.rpmuseradd -m zope-media
su – zope-media
svn co https://svn.lovelysystems.com/repos/……./teleport.mediaportal/trunk .
make
make run
That’s it :)
http://domu-12-31-33-00-04-5d.usma1.compute.amazonaws.com:8080/++skin++VOL/teleport.mediaportal