<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-9974736</id><updated>2009-10-26T03:07:06.789-07:00</updated><title type='text'>Brainfish Eat Fishbrain</title><subtitle type='html'>Technical information some people might find useful (or not).</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://brainfish-eat-fishbrain.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default?start-index=26&amp;max-results=25'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9974736.post-2455438941076776948</id><published>2009-10-26T03:07:00.000-07:00</published><updated>2009-10-26T03:07:06.795-07:00</updated><title type='text'>Cpanel: Monitoring :2082 logins</title><content type='html'>Simple script to send you all new logins of the day. Seeing something strange would trigger further research.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;chdir('/root');&lt;br /&gt;&lt;br /&gt;$d = `date +%m/%d/%Y`;&lt;br /&gt;chomp($d);&lt;br /&gt;&lt;br /&gt;@logins = `cat /usr/local/cpanel/logs/access_log|grep $d|awk '{print \$1 " " \$3}'|sort|uniq`;&lt;br /&gt;&lt;br /&gt;$x = "";&lt;br /&gt;&lt;br /&gt;foreach(@logins) {&lt;br /&gt; chomp; &lt;br /&gt; /(.*?)\ (.*)/;&lt;br /&gt; next if $2 eq "-";&lt;br /&gt; $z = `whois $1|grep addres|tail -n 1`;&lt;br /&gt; chomp($z);&lt;br /&gt; $x.="$z $1 $2\n";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (not -f "./latestscan") {&lt;br /&gt; `touch ./latestscan`;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$y = `cat ./latestscan`;&lt;br /&gt;&lt;br /&gt;exit if $y eq $x;&lt;br /&gt;&lt;br /&gt;open(F, "&gt;latestscan");&lt;br /&gt;print F $x; &lt;br /&gt;close F;&lt;br /&gt;&lt;br /&gt; $sendmail = "/usr/sbin/sendmail -t";&lt;br /&gt; open(SENDMAIL, "|$sendmail") or die "Cannot open $sendmail: $!"; &lt;br /&gt; print SENDMAIL "Reply-to: root\@myserver.org\n"; &lt;br /&gt; print SENDMAIL "Subject: Login report hostf1\n"; &lt;br /&gt; print SENDMAIL "To: alerts\@yourserver.com\n"; &lt;br /&gt; print SENDMAIL "Content-type: text/plain\n\n"; &lt;br /&gt; print SENDMAIL $x; &lt;br /&gt; close(SENDMAIL); &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-2455438941076776948?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2455438941076776948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2455438941076776948'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/10/cpanel-monitoring-2082-logins.html' title='Cpanel: Monitoring :2082 logins'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-6660484369905088090</id><published>2009-10-25T00:58:00.000-07:00</published><updated>2009-10-25T01:05:33.616-07:00</updated><title type='text'>Watching series; I don't want to touch my computer</title><content type='html'>When I watch series I don't want to touch my computer and I watch all episodes in one fell swoop; if I do something like mplayer *.mpg it crashes, so that doesn't work. This does, run like;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;./play "*.mpg"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;or &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;./play "*.avi"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The code;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;$a = "";&lt;br /&gt;foreach(@ARGV) {&lt;br /&gt; $a.=" " if $a; &lt;br /&gt; $a.=$_;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;while(1){foreach(glob("$a")){`mplayer -fs \"$_\"`}}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-6660484369905088090?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/6660484369905088090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/6660484369905088090'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/10/watching-series-i-dont-want-to-touch-my.html' title='Watching series; I don&apos;t want to touch my computer'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-4422931015331441041</id><published>2009-10-24T05:08:00.000-07:00</published><updated>2009-10-24T05:25:36.037-07:00</updated><title type='text'>Cpanel security: scanning for usage or upload of c99 shell script (or other scripts)</title><content type='html'>Sometimes users upload stuff to your server or use scripts you don't want used. To detect them fast, I wrote this script.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;    &lt;br /&gt;use Digest::Perl::MD5 'md5_hex';&lt;br /&gt;&lt;br /&gt;chdir('/root/');&lt;br /&gt;`touch ./scanned` if not -f "./scanned";&lt;br /&gt;&lt;br /&gt;%h = ();&lt;br /&gt;open(F, "scanned");&lt;br /&gt;while(&lt;F&gt;) {&lt;br /&gt; chomp;&lt;br /&gt; $h{$_} = 1;&lt;br /&gt;}&lt;br /&gt;close F;&lt;br /&gt;&lt;br /&gt;@x = `cd /etc/httpd/domlogs/; grep c99me *`;&lt;br /&gt;open(F, "&gt;&gt;scanned");&lt;br /&gt;$s = "";&lt;br /&gt;foreach(@x) {&lt;br /&gt; chomp;&lt;br /&gt; $m = md5_hex($_);&lt;br /&gt; next if $h{$m};&lt;br /&gt; print F "$m\n";&lt;br /&gt; $s.=$_."\n";&lt;br /&gt;}&lt;br /&gt;close F;&lt;br /&gt;&lt;br /&gt;if ($s) {&lt;br /&gt; $sendmail = "/usr/sbin/sendmail -t";&lt;br /&gt; open(SENDMAIL, "|$sendmail") or die "Cannot open $sendmail: $!"; &lt;br /&gt; print SENDMAIL "Reply-to: root\@myserver.org\n"; &lt;br /&gt; print SENDMAIL "Subject: Found some illegal stuff on server\n"; &lt;br /&gt; print SENDMAIL "To: alerts\@somewhere.com\n"; &lt;br /&gt; print SENDMAIL "Content-type: text/plain\n\n"; &lt;br /&gt; print SENDMAIL $s; &lt;br /&gt; close(SENDMAIL); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-4422931015331441041?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/4422931015331441041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/4422931015331441041'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/10/cpanel-security-scanning-for-usage-or.html' title='Cpanel security: scanning for usage or upload of c99 shell script (or other scripts)'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-5600240887093385330</id><published>2009-10-24T04:21:00.000-07:00</published><updated>2009-10-24T04:45:03.433-07:00</updated><title type='text'>Cpanel security: cron update all Wordpress installations on your server</title><content type='html'>Two simple scripts. Use with caution and at your own risk. Might eat your machine and piss off all your users. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;`rm -fR wordpress`;&lt;br /&gt;`wget http://wordpress.org/latest.zip`;&lt;br /&gt;`unzip latest.zip`;&lt;br /&gt;&lt;br /&gt;@all = `ls -la /home/|awk '{print \$3}'|grep -v root`;&lt;br /&gt;&lt;br /&gt;foreach(@all) {&lt;br /&gt; chomp;&lt;br /&gt; next if /^$/;&lt;br /&gt; `./updatewp $_`;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;$host = `hostname`; &lt;br /&gt;chomp($host);&lt;br /&gt;&lt;br /&gt;$u = $ARGV[0]; &lt;br /&gt;&lt;br /&gt;exit if !$u; # user as arg&lt;br /&gt;&lt;br /&gt;exit if not -f "/home/$u/public_html/wp-config.php"; # not wp install&lt;br /&gt;&lt;br /&gt;# you shouldn't actually have the readme.html, but if it's there it's a bit faster&lt;br /&gt;$v1 = `cat /home/$u/public_html/readme.html|grep Version &gt; dev/null`;&lt;br /&gt;$v1 =~ /Version\ (\d+\.\d+\.\d+)/;&lt;br /&gt;$v1 = $1; &lt;br /&gt;&lt;br /&gt;$v2 = `cat wordpress/readme.html|grep Version`;&lt;br /&gt;$v2 =~ /Version\ (\d+\.\d+\.\d+)/;&lt;br /&gt;$v2 = $1;&lt;br /&gt;&lt;br /&gt;exit if $v1 eq $v2; # already updated&lt;br /&gt;&lt;br /&gt;`cp -a wordpress /home/$u/wp_int`;&lt;br /&gt;&lt;br /&gt;`cp -rpf /home/$u/public_html/wp-config.php /home/$u/wp_int`;&lt;br /&gt;`cp -rpf /home/$u/public_html/wp-content/* /home/$u/wp_int/wp-content/`;&lt;br /&gt;`cp -rpf /home/$u/public_html/.htaccess /home/$u/wp_int/`;&lt;br /&gt;&lt;br /&gt;`chown $u.$u /home/$u/wp_int`;&lt;br /&gt;&lt;br /&gt;`cp -a /home/$u/public_html /home/$u/wpback\`date +%d%m%y\``;&lt;br /&gt;&lt;br /&gt;`cp -rpf /home/$u/wp_int/* /home/$u/public_html/`;&lt;br /&gt;&lt;br /&gt;`rm -fR /home/$u/wp_int`;&lt;br /&gt;&lt;br /&gt;$x = `lynx -dump http://$host/~$u/wp-admin/upgrade.php`;&lt;br /&gt;&lt;br /&gt;if ($x =~ /Database Upgrade Required/isgm) {&lt;br /&gt; `lynx -dump http://$host/~$u/wp-admin/upgrade.php?step=1\&amp;backto=`;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;print "Updated $u\n";&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-5600240887093385330?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/5600240887093385330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/5600240887093385330'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/10/cpanel-security-cron-update-all.html' title='Cpanel security: cron update all Wordpress installations on your server'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-482539225429425218</id><published>2009-08-03T07:37:00.000-07:00</published><updated>2009-08-03T07:46:37.762-07:00</updated><title type='text'>Mac OS X Firefox 3.5 intervals to 100% CPU about every 30 seconds</title><content type='html'>Yesterday suddenly my Firefox started to show the busy mouse pointer about every 30 seconds. Very annoying as it was completely unusable during about 5  seconds, and then 30 seconds later again etc. &lt;br /&gt;&lt;br /&gt;I removed my Profile in ~/Library and checked if it was FF or something in my profile. Ofcourse it was something in my profile. &lt;br /&gt;&lt;br /&gt;Checking my files I saw one file that looked 'odd' ; places.sqlite was rather huge (I do browser a lot), however sqlite can handle quite big databases. Anyway; I ran a&lt;br /&gt;&lt;br /&gt;rm -f places* &lt;br /&gt;&lt;br /&gt;and restarted FF. No more 100%. Fixed. &lt;br /&gt;&lt;br /&gt;What is going on I don't know; it looks like FF is running some kind of really bad query on that sqlite every +/- 30 s which is messing up the whole thing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-482539225429425218?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/482539225429425218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/482539225429425218'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/08/mac-os-x-firefox-35-intervals-to-100.html' title='Mac OS X Firefox 3.5 intervals to 100% CPU about every 30 seconds'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-904022534263290341</id><published>2009-06-30T01:18:00.000-07:00</published><updated>2009-06-30T01:25:19.623-07:00</updated><title type='text'>Checking/repairing all MySQL tables</title><content type='html'>Caution: on busy servers this will make a lot of load. Use only when you suspect/know tables are broken.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;$mysql = "/var/lib/mysql";&lt;br /&gt;&lt;br /&gt;@res = `cd $mysql; find .|grep MYD`;&lt;br /&gt;&lt;br /&gt;foreach(@res) {&lt;br /&gt; chomp;&lt;br /&gt; /\.\/(.*?)\/(.*?).MYD/;&lt;br /&gt; $tab = $1.".".$2;&lt;br /&gt; print `mysql --execute='repair table $tab'`; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-904022534263290341?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/904022534263290341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/904022534263290341'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/06/checkingrepairing-all-mysql-tables.html' title='Checking/repairing all MySQL tables'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-1524662282828530502</id><published>2009-02-06T03:44:00.001-08:00</published><updated>2009-02-06T04:45:56.852-08:00</updated><title type='text'>A simple, non bloated script for Amazon S3 backups (Linux, easy portable) - II - recurse to subdirs</title><content type='html'>To follow this, please read &lt;a href="http://brainfish-eat-fishbrain.blogspot.com/2009/01/simple-non-bloated-script-for-amazon-s3.html"&gt;this post&lt;/a&gt; first. &lt;br /&gt;&lt;br /&gt;We needed to backup our images from http://www.picturepush.com to S3 for our premium members so we were searching for a simple script to do that one time. As in my previous post; there is no such thing. Bloated, uninstallable shit is the only thing there is. &lt;br /&gt;&lt;br /&gt;So I changed the code a bit and added; &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;foreach($_SERVER["argv"] as $d) {&lt;br /&gt; recurse_copy($d, $d);&lt;br /&gt;}&lt;br /&gt;exit;&lt;br /&gt;&lt;br /&gt;function recurse_copy($d, $org) {&lt;br /&gt; foreach(glob("$d/*") as $d1) {&lt;br /&gt;  if ($d1=='..' || $d1=='.') continue;&lt;br /&gt;  if (is_dir($d1)) {&lt;br /&gt;   recurse_copy($d1, $org); &lt;br /&gt;  } else {&lt;br /&gt;   // put on s3&lt;br /&gt;   global $s3;&lt;br /&gt;   global $bucket;&lt;br /&gt;   $s3-&gt;putObjectFile($d1, $bucket, $d1);&lt;br /&gt;   echo "Storing: ".$d1."\n";&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;below the last;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;array_shift($_SERVER["argv"]);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-1524662282828530502?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/1524662282828530502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/1524662282828530502'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/02/simple-non-bloated-script-for-amazon-s3.html' title='A simple, non bloated script for Amazon S3 backups (Linux, easy portable) - II - recurse to subdirs'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-4984024590741954701</id><published>2009-01-03T09:01:00.000-08:00</published><updated>2009-01-03T11:01:40.355-08:00</updated><title type='text'>A simple, non bloated script for Amazon S3 backups (Linux, easily portable)</title><content type='html'>While searching for scripts to backup files from Linux -&gt; S3 (servers) I was surprised how difficult it was to find any nice, trim ones. There are &lt;span style="font-weight:bold;"&gt;huge&lt;/span&gt; java jars filled with crap to do it ofcourse;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;dbserv01:~# ls -lah js3tream.jar &lt;br /&gt;-rw-r--r-- 1 root root 3.2M 2007-12-19 15:07 js3tream.jar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Come on. 3.2M... What does that include? Windows Vista? &lt;br /&gt;&lt;br /&gt;Sure js3tream is actually nice software. Portable and it works. It's incredibly, mindbogglingly slow (but ofcourse, Java is not slow these days as many people tell me...) on my quad Xeon servers. But yeah, it has the features you would want. Except encryption of the files I upload; you arrange that in a different way please. Come to think of it; other features are missing as well.&lt;br /&gt;&lt;br /&gt;There is S3Sync in Ruby which is actually nice and working well, but still too much hassle to get going as simple script. But no complaints about the speed or size of that.&lt;br /&gt;&lt;br /&gt;Then there is some rsync thing in Python (I forgot the name and the HELLLLLLLLLLLLLLLLLL I went to to install it will not make me remember it any time soon).&lt;br /&gt;&lt;br /&gt;So, as almost all things in life, if you want it done right, you just have to do it yourself. I don't find it pretty at all, but it weighs in, including comments, at 36 kbs, which is, by far the smallest possible script I could find for the purpose I needed. &lt;br /&gt;&lt;br /&gt;I'm not counting rar or gpg as they are not included in the other ones either, but when counting them it wouldn't go over 1 mb. &lt;br /&gt;&lt;br /&gt;Download http://undesigned.org.za/2007/10/22/amazon-s3-php-class&lt;br /&gt;&lt;br /&gt;And install: &lt;br /&gt;&lt;br /&gt;- rar (apt-get install rar)&lt;br /&gt;- gpg (apt-get install gnupg)&lt;br /&gt;- php (apt-get install php5-cli php5-curl)&lt;br /&gt;&lt;br /&gt;Then edit the Amazon S3.php; put on top of it;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/php&lt;br /&gt;&lt;?php&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if (sizeof($_SERVER["argv"])&lt;4) {&lt;br /&gt; echo "Usage: ./s3backup bucket ident dir dir dir\n";&lt;br /&gt; exit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$bucket = $_SERVER["argv"][1];&lt;br /&gt;$ident = $_SERVER["argv"][2];&lt;br /&gt;&lt;br /&gt;define('PHPARTIALS_FILE_AWS_S3_ACCESSKEY', '');&lt;br /&gt;define('PHPARTIALS_FILE_AWS_S3_SECRETKEY', '');&lt;br /&gt;define('PHPARTIALS_FILE_RAR_ENCRYPT', '');&lt;br /&gt;define('PHPARTIALS_FILE_GPG_ENCRYPT', '');&lt;br /&gt;&lt;br /&gt;$s3 = new S3(PHPARTIALS_FILE_AWS_S3_ACCESSKEY, PHPARTIALS_FILE_AWS_S3_SECRETKEY);&lt;br /&gt;&lt;br /&gt;#print_r($s3-&gt;getBucket($bucket));exit;&lt;br /&gt;&lt;br /&gt;$l = $s3-&gt;listBuckets(true);&lt;br /&gt;&lt;br /&gt;if (!in_array($bucket, $l)) {&lt;br /&gt; $s3-&gt;putBucket($bucket, S3::ACL_PRIVATE);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$fn = $ident."-".strftime('%d%m%y%H%M').".rar";&lt;br /&gt;&lt;br /&gt;array_shift($_SERVER["argv"]);&lt;br /&gt;array_shift($_SERVER["argv"]);&lt;br /&gt;array_shift($_SERVER["argv"]);&lt;br /&gt;&lt;br /&gt;$f = implode(' ', $_SERVER["argv"]);&lt;br /&gt;&lt;br /&gt;$cmd = "rar a -hp".PHPARTIALS_FILE_RAR_ENCRYPT." $fn $f";&lt;br /&gt;&lt;br /&gt;echo `$cmd`;&lt;br /&gt;&lt;br /&gt;$fn1=$fn.".enc";&lt;br /&gt;&lt;br /&gt;$cmd = "gpg --batch --yes --trust-model always --encrypt --recipient '".PHPARTIALS_FILE_GPG_ENCRYPT."' -o $fn1 $fn";&lt;br /&gt;&lt;br /&gt;echo `$cmd`;&lt;br /&gt;&lt;br /&gt;$s3-&gt;putObjectFile($fn, $bucket, baseName($fn1));&lt;br /&gt;&lt;br /&gt;print "Backup created!\nSize: ".filesize($fn1)." bytes\n";&lt;br /&gt;&lt;br /&gt;unlink($fn);&lt;br /&gt;unlink($fn1);&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Rename the S3.php  to something like s3backup and chmod 700 s3backup to make it executable.&lt;br /&gt;&lt;br /&gt;You put your 2 keys for Amazon S3 in the Amazon defines, a password for rarring in the RAR password define and the name of the user your public key is for on that system to GPG encrypt the rar. &lt;br /&gt;&lt;br /&gt;To add a public key for GPG, just put your GPG Public key in a file, say /root/mypub.key and run;&lt;br /&gt;&lt;br /&gt;gpg -a --import /root/mypub.key&lt;br /&gt;&lt;br /&gt;And all will be fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-4984024590741954701?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/4984024590741954701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/4984024590741954701'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2009/01/simple-non-bloated-script-for-amazon-s3.html' title='A simple, non bloated script for Amazon S3 backups (Linux, easily portable)'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-301869886522588365</id><published>2008-11-24T19:55:00.000-08:00</published><updated>2008-11-25T05:01:09.319-08:00</updated><title type='text'>Filthy Rotten Scriptkiddies - Blackmailing Siteowners</title><content type='html'>A friend of mine owns a site which has very little traffic and sells a niche product. Because he gets so little traffic, alarm bells immediately sound when suddenly there is a spike. &lt;br /&gt;&lt;br /&gt;If there would be a spike, he would be rich probably, but the chances of that happening are very slim. &lt;br /&gt;&lt;br /&gt;Anyway, this night, the guy called me up at 3:30 saying he received an email from some hotmail address saying something like ;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;I understand how much revinue you bring in each month, I can bring that down to 0 if I wish. Think I'm kidding? Think this is a joke?&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And then his demands. &lt;br /&gt;&lt;br /&gt;So, me thinking this was indeed a joke, asking why he )(@#%()#@% woke me. But it wasn't a joke. The site was down. Very much so for 1.5 hour already. Costing my friend money. &lt;br /&gt;&lt;br /&gt;A bit groggy from sleeping I could not imagine this being anything else than some lame DOS attack; one or a few computers bonking away on :80. &lt;br /&gt;&lt;br /&gt;Unfortunately that was not the case at all. &lt;br /&gt;&lt;br /&gt;This was a quite (for this kind of lame threat / blackmail) heavy DDOS. After a few minutes I already collected (and blocked) over 200 unique ips (from different classes mostly). &lt;br /&gt;&lt;br /&gt;In this blog I have shown more than ones some ideas for catching and blocking DDOS attacks from within Linux and this one was rather a simple one and could be simply blocked using; &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flexlists.com/view.php?list_id=6192#d::4"&gt;List of Linux tricks&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Few notes here; Apache (or whatever you might use) queues all those income connections and leaves them connected even though they are blocked. Because of this, &lt;br /&gt;during the attack, I run from the cron; */10 * * * * service httpd restart. Making Apache immediately kill of those bad connections, but finish off the real ones with a real response. At least you'll have service for most people using this method.&lt;br /&gt;&lt;br /&gt;Ofcourse it required a bunch of tweaking as the attacker changed his strategy quite often  to make it more difficult. &lt;br /&gt;&lt;br /&gt;I don't get people who do this and I certainly don't understand how they can mount such a huge attack with so many different IPs.&lt;br /&gt;&lt;br /&gt;Edit: attack has been going on for 9 hours now... site doing fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-301869886522588365?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/301869886522588365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/301869886522588365'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/11/filthy-rotten-scriptkiddies.html' title='Filthy Rotten Scriptkiddies - Blackmailing Siteowners'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-2352789961431239965</id><published>2008-11-13T15:11:00.000-08:00</published><updated>2008-11-13T16:19:55.438-08:00</updated><title type='text'>MacOSX / Bootcamp / Installing Windows XP without SPs / there is not enough disk space on $ntservicepackuninstall$ to install service pack bla</title><content type='html'>Sometimes you have to do things you don't want. Today I needed to install something under Windows to convert some fileformat (media file format) for which I cannot find Linux or Mac converters. Not even Mplayer can play it. Only some weird proprietary Windows app. &lt;br /&gt;&lt;br /&gt;So basically; I needed Windows. And I hate Windows. And not without passion; I really hate it. But ok, enough about that. &lt;br /&gt;&lt;br /&gt;I have a Mac Mini standing on my desk gathering dust (oh did I mention I hate Mac OS X too?), so I thought ; I can install on that. &lt;br /&gt;&lt;br /&gt;Not that easy. Requires an XP disk with SP2. And ofcourse I didn't have that. As I really don't want to pay for stuff I already have, I took an XP version from 2001 (so without any SPs) and tried to find a way to install that on the Mac Mini. Legal as I don't even have the computer anymore on which is belonged, but I have the 'authentic Windows crap sticker' still.&lt;br /&gt;&lt;br /&gt;The installation from within Bootcamp went 'smooth', although Windows doesn't want to shutdown or restart, you have to force it down by holding the shutdown button. &lt;br /&gt;&lt;br /&gt;And almost none of the software/drivers Apple provides work without SP2. Even worse (well... not much worse); Mac OS X doesn't boot anymore. &lt;br /&gt;&lt;br /&gt;Anyway; I got the SP2 download and burnt it on a CD under Linux and tried to install it under the non-SP version on the Mac Mini. Unfortunately, it started yelping about some missing 4 mb's of space....... 4 mbs. Ofcourse I have more than 20 gb free so that could not be right. &lt;br /&gt;&lt;br /&gt;Quite annoyingly, the Mac community is not of the technical details; when searching for these kind of problems, people keep repeating in forums that I insulted my Mac by installing Windows OR that I did not read and MUST HAVE SP2 Windows install CD OR that I should just reinstall everything. All very helpful. Not. &lt;br /&gt;&lt;br /&gt;So I was faced with two problems;&lt;br /&gt;&lt;br /&gt;- no more Mac OS X&lt;br /&gt;- Windows couldn't install the SP so I couldn't install any drivers etc&lt;br /&gt;&lt;br /&gt;The former was not that important for me as I don't like Mac OS X that much and certainly never use it if I can avoid it. &lt;br /&gt;&lt;br /&gt;But for the latter I started this whole adventure, so I couldn't give that up.&lt;br /&gt;&lt;br /&gt;I read all messages about this problem and the solution turned out to be very (very) simple;&lt;br /&gt;&lt;br /&gt;Windows-R (Start-&gt;Run)&lt;br /&gt;regedit&lt;br /&gt;&lt;br /&gt;Add a String &lt;br /&gt;&lt;br /&gt;key = BootDir &lt;br /&gt;value = C:\&lt;br /&gt;&lt;br /&gt;To &lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Setup]&lt;br /&gt;&lt;br /&gt;And rerun the SP2 installer.&lt;br /&gt;&lt;br /&gt;Why didn't they just SAY so?&lt;br /&gt;&lt;br /&gt;Anyway; if/when I have Mac OS X back I'll report it here and people can use nice old  CD's of XP they find in car boot sales, instead of paying money to that company we all love.&lt;br /&gt;&lt;br /&gt;Edit: Well, that was ofcourse kind of simple; &lt;br /&gt;&lt;br /&gt;- remove the read only flag from c:\boot.ini&lt;br /&gt;- edit boot.ini&lt;br /&gt;- put at the end c:\CHAIN0="Mac OS X"&lt;br /&gt;- save&lt;br /&gt;- put this file in you c:\&lt;br /&gt;- reboot&lt;br /&gt;&lt;br /&gt;Not Boot Camp, but working fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-2352789961431239965?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2352789961431239965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2352789961431239965'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/11/macosx-bootcamp-installing-windows-xp.html' title='MacOSX / Bootcamp / Installing Windows XP without SPs / there is not enough disk space on $ntservicepackuninstall$ to install service pack bla'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-455743119063774848</id><published>2008-10-04T11:40:00.000-07:00</published><updated>2008-10-04T11:44:08.961-07:00</updated><title type='text'>Creating databases in cpanel remotely</title><content type='html'>Lately I was wondering how one would go about creating databases in cpanel without having to log on. Do it from PHP or something and create a somewhat 'nicer' interface to that 'nice' cpanel stuff.&lt;br /&gt;&lt;br /&gt;It proved to be trivial to do anything with the system; that is in face kind of nice and has been a relief for me as I thought it would be (much) more difficult.&lt;br /&gt;&lt;br /&gt;Here is a code snippet how to do this easily. It return &lt;a href="http://www.phpartials.com"&gt;PHPartialsResult&lt;/a&gt;, but you can replace that with 'true' or something.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  function remote_account_create_db($host, $user, $pass, $dbname) {&lt;br /&gt;   $conn = "http://$user:$pass@$host:2082/frontend/x3/sql/addb.html?db=$dbname";&lt;br /&gt;   file_get_contents($conn); &lt;br /&gt;   return PHPartialsResult::ok();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function remote_account_create_dbuser($host, $user, $pass, $_user, $_pass) {&lt;br /&gt;   $conn = "http://$user:$pass@$host:2082/frontend/x3/sql/adduser.html?user=$_user&amp;pass=$pass&amp;pass2=$pass";&lt;br /&gt;   file_get_contents($conn); &lt;br /&gt;   return PHPartialsResult::ok(); &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function remote_account_create_dbuserconnection($host, $user, $pass, $_user, $_db) {&lt;br /&gt;   $conn = "http://$user:$pass@$host:2082/frontend/x3/sql/addusertodb.html?ALL=ALL&amp;user=$_user&amp;db=$_db";&lt;br /&gt;   file_get_contents($conn); &lt;br /&gt;   return PHPartialsResult::ok(); &lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-455743119063774848?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/455743119063774848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/455743119063774848'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/10/creating-databases-in-cpanel-remotely.html' title='Creating databases in cpanel remotely'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-215441226113983491</id><published>2008-04-25T15:05:00.000-07:00</published><updated>2008-04-28T07:26:04.215-07:00</updated><title type='text'>Using tcpproxy for http forwarding? Add X-Forwarded-For!</title><content type='html'>TCPProxy is one of the most beautiful tools I know of; it was nicely programmed, but above all; it has no bugs. None. We are routing millions of pageviews a day of hundreds of thousands of unique users through it and it has never let me down. It is fast, uses almost no CPU and is very very robust (I miss FTP support, but further it is totally perfect). &lt;br /&gt;&lt;br /&gt;This unlike Apache (proxy pass) or Squid or the many other, less known, proxies I tried. Apache is especially crappy; proxy pass is riddled with bugs; under load it simply is unusable. And most of them are feature-heavy; too feature heavy; they are a pain to set up, but trivial things like not binding to 0.0.0.0 etc or simple config files they have not. &lt;br /&gt;&lt;br /&gt;We have the necessity to route web traffic via different machines in different places and ofcourse I wanted to use tcpproxy for the task, but it has no x-forwarded-for and so we were pissing our users (with forums, blogs etc) off. So I decided to hack tcpproxy for this. And it works. Serving the millions of pages through it. With x-forwarded-for. &lt;br /&gt;&lt;br /&gt;This was tested on 1.1.9; &lt;br /&gt;&lt;br /&gt;In tcpproxy.c, search for these lines;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int proxy_request(config_t *x, int cfd)&lt;br /&gt;{&lt;br /&gt;int     sfd, rc, bytes;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and change to: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int     sfd, rc, bytes, first=1, i;&lt;br /&gt;char    *hp, *hp1;&lt;br /&gt;char    tmp[4096];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;then search for;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  else if (write(sfd, buffer, bytes) != bytes) {&lt;br /&gt;                                syslog(LOG_NOTICE, "client write() error");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and change that to; &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;else {&lt;br /&gt;if (first &amp;&amp; (&lt;br /&gt; (buffer[0] == 'G' &amp;&amp; buffer[1] == 'E' &amp;&amp; buffer[2] == 'T') ||&lt;br /&gt; (buffer[0] == 'P' &amp;&amp; buffer[1] == 'O' &amp;&amp; buffer[2] == 'S' &amp;&amp; buffer[3] == 'T') ||&lt;br /&gt; (buffer[0] == 'P' &amp;&amp; buffer[1] == 'U' &amp;&amp; buffer[2] == 'T')&lt;br /&gt; )) {&lt;br /&gt;&lt;br /&gt; hp = &amp;buffer;&lt;br /&gt; *(hp+bytes)='\0';&lt;br /&gt; hp = strstr(buffer, "\r\n\r\n");&lt;br /&gt; if (hp) {&lt;br /&gt;  hp1 = &amp;buffer;&lt;br /&gt;  i = abs(hp1-hp);&lt;br /&gt;  *hp = '\0';&lt;br /&gt;  memcpy(tmp, buffer, bytes+1);&lt;br /&gt;  strupr(buffer);&lt;br /&gt;  if (!strstr(buffer, "X-FORWARDED-FOR")) {&lt;br /&gt;   sprintf(buffer, "%s\r\nX-Forwarded-For: %s\r", tmp, x-&gt;client_ip);&lt;br /&gt;   hp = &amp;tmp;&lt;br /&gt;   hp += i + 1;&lt;br /&gt;   i = bytes - i - 1;&lt;br /&gt;   bytes = i + strlen(buffer);&lt;br /&gt;   hp1 = &amp;buffer;&lt;br /&gt;   hp1 += strlen(buffer);&lt;br /&gt;   memcpy(hp1, hp, i);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;first = 0;&lt;br /&gt;&lt;br /&gt;if (write(sfd, buffer, bytes) != bytes) {&lt;br /&gt;                                syslog(LOG_NOTICE, "client write() error");&lt;br /&gt; &lt;br /&gt;           break;&lt;br /&gt;                                }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Compile it and it'll add X-Forwarded-For.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-215441226113983491?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/215441226113983491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/215441226113983491'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/04/using-tcpproxy-for-http-forwarding-add.html' title='Using tcpproxy for http forwarding? Add X-Forwarded-For!'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-2305055615314742618</id><published>2008-04-09T04:41:00.000-07:00</published><updated>2008-04-09T04:55:32.731-07:00</updated><title type='text'>Debootstrap must be the most brilliant thing ever conceived</title><content type='html'>Are you lazy?&lt;br /&gt;Are you tired of installing the same shit across Linux servers?&lt;br /&gt;Are you sick of compiling the latest &amp; greatest bag of mplayer/ffmpeg/lame on all your systems? &lt;br /&gt;Are you becoming suicidal when someone asks you to send you a 'working out of the box version'? &lt;br /&gt;&lt;br /&gt;You don't need to be :) Install once, run anywhere (on Linux ofcourse, but what else would you run anyway huh); &lt;br /&gt;&lt;br /&gt;Install debootstrap;&lt;br /&gt;&lt;br /&gt;apt-get install debootstrap&lt;br /&gt;&lt;br /&gt;I personally find it nicest to have everything in a file (so you can easily copy one file and leave it at that);&lt;br /&gt;&lt;br /&gt;First make a loopdevice (3 gb file); &lt;br /&gt;&lt;br /&gt;dd if=/dev/zero of=/myETCH bs=1M count=3000&lt;br /&gt;&lt;br /&gt;Set up kernel loopdevice if you didn't;&lt;br /&gt;&lt;br /&gt;insmod loop.o&lt;br /&gt;&lt;br /&gt;Set up the loop device;&lt;br /&gt;&lt;br /&gt;losetup /dev/loop0 /myETCH&lt;br /&gt;&lt;br /&gt;Format the loopdevice with ext3;&lt;br /&gt;&lt;br /&gt;mkfs.ext3 /dev/loop0&lt;br /&gt;mount /dev/loop0 /myETCH&lt;br /&gt;&lt;br /&gt;then remove everything again; &lt;br /&gt;&lt;br /&gt;umount /dev/loop0&lt;br /&gt;losetup -d /dev/loop0&lt;br /&gt;&lt;br /&gt;Your loopdevice is now ready for use! &lt;br /&gt;&lt;br /&gt;mount it with;&lt;br /&gt;&lt;br /&gt;mount -t ext3 /myEtch /etchinstall -o loop=/dev/loop0&lt;br /&gt;&lt;br /&gt;If you do not want a loopback device, simply run; &lt;br /&gt;&lt;br /&gt;mkdir /etchinstall&lt;br /&gt;&lt;br /&gt;After this you can proceed with installing Debian etch; &lt;br /&gt;&lt;br /&gt;debootstrap etch /etchinstall&lt;br /&gt;&lt;br /&gt;Wait for it to be done.&lt;br /&gt;&lt;br /&gt;Then mount proc; &lt;br /&gt;&lt;br /&gt;mount -t proc proc /etchinstall/proc&lt;br /&gt;&lt;br /&gt;then you can chroot it; &lt;br /&gt;&lt;br /&gt;chroot /etchinstall&lt;br /&gt;&lt;br /&gt;And there you are; your own nice, contained version of Debian Etch.&lt;br /&gt;&lt;br /&gt;Install whatever you want into it. Provide your friends with the loop file /myEtch when you want to have 100% the environment as you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-2305055615314742618?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2305055615314742618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2305055615314742618'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/04/debootstrap-must-be-most-brilliant.html' title='Debootstrap must be the most brilliant thing ever conceived'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-5635721923766796428</id><published>2008-03-31T15:50:00.000-07:00</published><updated>2008-03-31T15:58:29.115-07:00</updated><title type='text'>Heavy encrypting files on your linux box</title><content type='html'>After some nasty run-in with reality I decided to day to take better care of my passwords. By encrypting them with GnuPG, I thought I would stand a much better chance when my laptop gets stolen. I am lazy so I already have my HD encrypted, but, for the super paranoid, as I am becoming more and more, I now also have my passes seperate encrypted in a vault file with 4096 gpg encryption. &lt;br /&gt;&lt;br /&gt;How? Very simple; first generate a pub/priv key pair; &lt;br /&gt;&lt;br /&gt;gpg --gen-key&lt;br /&gt;&lt;br /&gt;then add two files to your path;&lt;br /&gt;&lt;br /&gt;enc;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;$file = $ARGV[0];&lt;br /&gt;$file1 = $ARGV[1]; &lt;br /&gt;&lt;br /&gt;if (!$file or !$file1) {&lt;br /&gt; print "Usage: ./enc input output\n";&lt;br /&gt; exit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;print `gpg --encrypt --recipient 'Your Name' -o $file1 $file`;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;dec; &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;$file = $ARGV[0]; &lt;br /&gt;&lt;br /&gt;if (!$file) {&lt;br /&gt; print "Usage: dec input\n"; &lt;br /&gt; exit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;print `gpg --decrypt $file`;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then make sure you have zero writing tool to delete the original, to be encrypted, file and you're all done :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-5635721923766796428?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/5635721923766796428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/5635721923766796428'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/03/heavy-encrypting-files-on-your-linux.html' title='Heavy encrypting files on your linux box'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-5877175446326850371</id><published>2008-03-09T21:09:00.000-07:00</published><updated>2008-03-09T21:15:45.573-07:00</updated><title type='text'>Mysql (or other) dump in PHP</title><content type='html'>I a lot of sourcode I see the calling of mysqldump to dump tables. Doing so needs all kind of OS dependent path settings and so on, so I thought I share a simple function for dumping a table from MySQL in PHP: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  function _mysqlDump($table, $toFile) {&lt;br /&gt;   $f = fopen($toFile, "w");&lt;br /&gt;   $qry = "select * from $table";&lt;br /&gt;   $q = mysql_query($qry);&lt;br /&gt;   if (!$q) {&lt;br /&gt;    echo "Could not dump $table\n";&lt;br /&gt;    return;&lt;br /&gt;   }&lt;br /&gt;   while($r = mysql_fetch_assoc($q)) {&lt;br /&gt;    $i1 = ""; $i2 = "";&lt;br /&gt;    foreach($r as $k=&gt;$v) {&lt;br /&gt;     if ($i1) {$i1.=","; $i2.=",";}&lt;br /&gt;     $i1.=$k;&lt;br /&gt;     $v = mysql_real_escape_string($v);&lt;br /&gt;     $i2.="'$v'";&lt;br /&gt;    }&lt;br /&gt;    fputs($f, "insert into $table ($i1) values ($i2);\n");&lt;br /&gt;   }&lt;br /&gt;   fclose($f);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;&lt;br /&gt;The advantage of this is that it creates total inserts which is handy when you want to recreate the database with the content intact.&lt;br /&gt;&lt;br /&gt;Inserting the content back into the database is trivial ofcourse: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   $f = fopen($toFile, "r");&lt;br /&gt;   while($s=fgets($f, 128000)) {&lt;br /&gt;    if (trim($s)) mysql_query($s);&lt;br /&gt;   }&lt;br /&gt;   fclose($f);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-5877175446326850371?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/5877175446326850371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/5877175446326850371'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/03/mysql-or-other-dump-in-php.html' title='Mysql (or other) dump in PHP'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-1588077216349802149</id><published>2008-03-08T21:28:00.000-08:00</published><updated>2008-03-08T21:44:40.854-08:00</updated><title type='text'>Commandline Rapidshare.com downloader</title><content type='html'>Sometimes you would want to download files from rapidshare via the commandline because the webinterface sucks. Did I say sometimes? You *never* want to use the webinterface :)&lt;br /&gt;&lt;br /&gt;You have to have a premium account to use it.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;$user = $ARGV[0];&lt;br /&gt;$pass = $ARGV[1];&lt;br /&gt;$file = $ARGV[2];&lt;br /&gt;&lt;br /&gt;`mkdir ~/.cookies; wget --save-cookies ~/.cookies/rapidshare --post-data "login=$user&amp;password=$pass" -O - https://ssl.rapidshare.com/cgi-bin/premiumzone.cgi &gt; /dev/null`;&lt;br /&gt;&lt;br /&gt;open(F, $file);&lt;br /&gt;while(&lt;F&gt;) {&lt;br /&gt; chomp;&lt;br /&gt; next if /^$/;&lt;br /&gt; print `wget -c --load-cookies ~/.cookies/rapidshare $_`;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-1588077216349802149?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/1588077216349802149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/1588077216349802149'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/03/commandline-rapidsharecom-downloader.html' title='Commandline Rapidshare.com downloader'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-8834315380992809602</id><published>2008-03-08T00:50:00.000-08:00</published><updated>2008-03-08T00:59:17.887-08:00</updated><title type='text'>Automatic destruction of phishing sites</title><content type='html'>The Americans are getting worse with their phishing 'resolutions'; a lot of provider down your server and others implement draconian measures like giving you less than 1 hour to remove the site before they shutdown your equipment. Because we are a small company, we cannot sit behind email 24/7. So we had to be smart instead of hiring more people. &lt;br /&gt;&lt;br /&gt;How does it work? Make an 'abuse' gmail account, have your mailsystem forward all abuse mails to it. Then run the below program in CRON */5. It'll basically remove all scamming sites from existence after a complaint.&lt;br /&gt;&lt;br /&gt;Ofcourse you need to tweak it for your purpose/host. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/php&lt;br /&gt;&lt;?php&lt;br /&gt;&lt;br /&gt;$mbox = imap_open ("{pop.gmail.com:995/pop3/ssl/novalidate-cert}INBOX", &lt;br /&gt;        "xxyyzzaabbccdd@gmail.com", "yourpass");&lt;br /&gt;&lt;br /&gt;$msgs=imap_headers($mbox);&lt;br /&gt;foreach ($msgs as $index=&gt;$header) {&lt;br /&gt; $content = imap_body($mbox, $index+1);  &lt;br /&gt; $header = imap_fetchheader($mbox, $index+1);&lt;br /&gt; $msg = $content;&lt;br /&gt; $content = $header.$content;&lt;br /&gt;&lt;br /&gt; $res  = array();&lt;br /&gt;&lt;br /&gt; preg_match("/Subject: (.*)/", $content, $res);&lt;br /&gt; $res = $res[1];&lt;br /&gt; if (strpos($res, "Abuse")!==false) {&lt;br /&gt;  $res1=array();&lt;br /&gt;  preg_match_all("/(.*.yourdomain.com)/", $content, $res1);&lt;br /&gt;&lt;br /&gt;  foreach($res1 as $r) {&lt;br /&gt;   foreach($r as $r1) {&lt;br /&gt;    $i = strpos($r1, ".yourdomain.com")-1; &lt;br /&gt;    $user= "";&lt;br /&gt;    for(;$i&gt;0;$i--) {&lt;br /&gt;     if (in_array($r1[$i], array(' ', '/', '\n', '\r'))) break;&lt;br /&gt;     $user=$r1[$i].$user;&lt;br /&gt;    }  &lt;br /&gt;    kill_user($user);&lt;br /&gt;&lt;br /&gt;    mail("abuse@yourhoster.com", "Re: $res", &lt;br /&gt;        "Dear,\nThis account has been removed.\n\nThank you,\nA Friend\n\n\n$msg", &lt;br /&gt;        "From: afriend@yourdomain.com\n");&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;imap_expunge($mbox);&lt;br /&gt;imap_close($mbox);&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-8834315380992809602?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/8834315380992809602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/8834315380992809602'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/03/automatic-destruction-of-phishing-sites.html' title='Automatic destruction of phishing sites'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-6545654473849601643</id><published>2008-03-03T13:49:00.000-08:00</published><updated>2008-03-03T13:55:34.165-08:00</updated><title type='text'>postfix, cannot connect to mysql server localhost</title><content type='html'>When trying to run Postfix with virtual maps in MySQL, you can get the following error: &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;connect to mysql server localhost: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' postfix&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This error is because postfix is running in chroot /var/spool/postfix. So it cannot find the unix socket for MySQL.&lt;br /&gt;&lt;br /&gt;If you have the option to run mysql on 127.0.0.1 or on another IP, simply go to;&lt;br /&gt;&lt;br /&gt;/etc/postfix&lt;br /&gt;&lt;br /&gt;run;&lt;br /&gt;&lt;br /&gt;grep localhost *&lt;br /&gt;&lt;br /&gt;and replace all localhost to 127.0.0.1 or the IP in all files starting with mysql-virtual.&lt;br /&gt;&lt;br /&gt;If you insist on running via unix sockets, you can simply fix it by running; &lt;br /&gt;&lt;br /&gt;mkdir /var/spool/postfix/var&lt;br /&gt;mount --bind /var /var/spool/postfix/var&lt;br /&gt;&lt;br /&gt;Ater this, all will work fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-6545654473849601643?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/6545654473849601643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/6545654473849601643'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/03/postfix-cannot-connect-to-mysql-server.html' title='postfix, cannot connect to mysql server localhost'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-2364332566011946032</id><published>2008-02-29T11:24:00.000-08:00</published><updated>2008-02-29T11:32:35.743-08:00</updated><title type='text'>Stupid DDOS attacks - a simple script and common sense</title><content type='html'>Today we had some fun; a DDOS attack from  some kind of botnet. We can hundreds (thousands) of IPs sending something to Apache like;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$MyNick Aando|$Lock EXTENDEDPROT&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The new Linux kernel iptables can DROP/REJECT based on strings, but I was not going to recompile and install an experimental kernel for this 'little problem', risking more downtime than need-be. &lt;br /&gt;&lt;br /&gt;So I used sniffing to detect problems:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;tcpdump -n -vvv -i eth0 -A|grep -B 1 \$MyNick|grep \.80: &gt; /tmp/ip.log&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(grepping for port .80: because it is attacking my webserver)&lt;br /&gt;&lt;br /&gt;Then a killer perl script to block the offending IPs:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;%ips=();&lt;br /&gt;open(F, "tail -f /tmp/ip.log|");&lt;br /&gt;while(&lt;F&gt;){&lt;br /&gt; chomp;&lt;br /&gt; /.*\)\ (\d+?\.\d+?\.\d+?\.\d+?)\..*?\&gt;/;&lt;br /&gt; $ip = $1;&lt;br /&gt; next if $ip=~/127.0.0/;&lt;br /&gt; if (!$ips{$ip}) {&lt;br /&gt;  $ips{$ip} = 1;&lt;br /&gt;  `iptables -A INPUT -p tcp  --source $ip --dport 80 -j REJECT`;&lt;br /&gt;  print "$ip blocked\n";&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;close F;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This'll do it; server freed up and we could serve again nicely :) No need for recompiling at all!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-2364332566011946032?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2364332566011946032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2364332566011946032'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/02/stupid-ddos-attacks-simple-script-and.html' title='Stupid DDOS attacks - a simple script and common sense'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-2551067388688195207</id><published>2008-02-28T02:07:00.000-08:00</published><updated>2008-02-28T02:08:28.455-08:00</updated><title type='text'>Apache logs: simple log analyzer in Perl - II</title><content type='html'>I added top 30 and bandwidth / minute; &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;# get handler to the logfile&lt;br /&gt;open(LOG_FILE, "tail -f /var/log/httpd/access_log.users|");&lt;br /&gt;&lt;br /&gt;# start the main loop&lt;br /&gt;%users = ();&lt;br /&gt;$cp=0;&lt;br /&gt;$ct=time();&lt;br /&gt;while(&lt;LOG_FILE&gt;) {&lt;br /&gt; chomp;&lt;br /&gt; &lt;br /&gt; $cp = time() + 5*60 if $cp==0;&lt;br /&gt; if (-f "/tmp/killtraffic") {&lt;br /&gt;  %users=();&lt;br /&gt;  `rm -f /tmp/killtraffic`;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; my $t1 = time(); # timestamp for checkpointing&lt;br /&gt;&lt;br /&gt; my ($dom, $ip, $date, $req, $code, $ref, $client, $in, $out) &lt;br /&gt;                = /(.*?)\ (.*?)\ .*?\[(.*?)\]\ \"(.*?)\"\ (.*?)\ .*?\"(.*?)\"\ \"(.*?)\"\ (.*?)\ (.*)/;&lt;br /&gt;&lt;br /&gt; my ($method, $uri, $proto) = ($req =~ /(.*?)\ (.*?)\ (.*)/);&lt;br /&gt;&lt;br /&gt; my $get = 0;&lt;br /&gt; if ($uri =~ /(.*?)\?(.*)$/) {&lt;br /&gt;  $uri = $1;&lt;br /&gt;  $get = $2;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; my $url = $dom;&lt;br /&gt;&lt;br /&gt; if (!$users{$url}) {&lt;br /&gt;  $users{$url} = $in + $out;&lt;br /&gt; } else {&lt;br /&gt;  $users{$url} = $users{$url} + $in + $out;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; $cpc = time();&lt;br /&gt; if ( $cpc &gt; $cp ) {&lt;br /&gt;  $cp=0; &lt;br /&gt;  my $s="";&lt;br /&gt;  $m = (time()-$ct) / 60;&lt;br /&gt;  $count = 0;&lt;br /&gt;  foreach(keys %users) {&lt;br /&gt;   $s.=($users{$_}/1024)." kb - ".($users{$_}/1024/$m)." kb/min - ".$_."\n";&lt;br /&gt;   $count++; &lt;br /&gt;   last if $count&gt;30;&lt;br /&gt;  }&lt;br /&gt;  `echo "Count started $m minutes ago\n" &gt; /tmp/traffic.log`;&lt;br /&gt;  `echo "$s"|sort -n -r &gt;&gt; /tmp/traffic.log`;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# never get here:&lt;br /&gt;close LOG_FILE;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-2551067388688195207?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2551067388688195207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/2551067388688195207'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/02/apache-logs-simple-log-analyzer-in-perl_28.html' title='Apache logs: simple log analyzer in Perl - II'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-3213164773937451252</id><published>2008-02-28T01:38:00.000-08:00</published><updated>2008-02-28T01:45:19.123-08:00</updated><title type='text'>Apache logs: simple log analyzer in Perl</title><content type='html'>Get Apache to log your bandwidth by putting in httpd.conf/apache2.conf;&lt;br /&gt;&lt;br /&gt;LogFormat "%V %h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\" \"%{User-agent}i\" %I %O" combined_io&lt;br /&gt;CustomLog /var/log/httpd/access_log.users combined_io&lt;br /&gt;&lt;br /&gt;And run the following perl script;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;# get handler to the logfile&lt;br /&gt;open(LOG_FILE, "tail -f /var/log/httpd/access_log.users|");&lt;br /&gt;&lt;br /&gt;# start the main loop&lt;br /&gt;%users = ();&lt;br /&gt;$cp=0;&lt;br /&gt;while(&lt;LOG_FILE&gt;) {&lt;br /&gt; chomp;&lt;br /&gt; &lt;br /&gt; $cp = time() + 5*60 if $cp==0; # set to refresh the traffic.log file every 5 min&lt;br /&gt; &lt;br /&gt; my $t1 = time(); # timestamp for checkpointing&lt;br /&gt;&lt;br /&gt; my ($dom, $ip, $date, $req, $code, $ref, $client, $in, $out) &lt;br /&gt;                = /(.*?)\ (.*?)\ .*?\[(.*?)\]\ \"(.*?)\"\ (.*?)\ .*?\"(.*?)\"\ \"(.*?)\"\ (.*?)\ (.*)/;&lt;br /&gt;&lt;br /&gt; my ($method, $uri, $proto) = ($req =~ /(.*?)\ (.*?)\ (.*)/);&lt;br /&gt;&lt;br /&gt; my $get = 0;&lt;br /&gt; if ($uri =~ /(.*?)\?(.*)$/) {&lt;br /&gt;  $uri = $1;&lt;br /&gt;  $get = $2;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; my $url = $dom;&lt;br /&gt;&lt;br /&gt; if (!$users{$url}) {&lt;br /&gt;  $users{$url} = $in + $out;&lt;br /&gt; } else {&lt;br /&gt;  $users{$url} = $users{$url} + $in + $out;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; $cpc = time();&lt;br /&gt; if ( $cpc &gt; $cp ) {&lt;br /&gt;  $cp=0; &lt;br /&gt;  my $s = "";&lt;br /&gt;  foreach(keys %users) {&lt;br /&gt;   $s.=($users{$_}/1024)." kb - ".$_."\n";&lt;br /&gt;  }&lt;br /&gt;  `echo "$s"|sort -n -r &gt; /tmp/traffic.log`;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# never get here:&lt;br /&gt;close LOG_FILE;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;By viewing /tmp/traffic.log, you'll see what/who is using most traffic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-3213164773937451252?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/3213164773937451252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/3213164773937451252'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/02/apache-logs-simple-log-analyzer-in-perl.html' title='Apache logs: simple log analyzer in Perl'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-1486353920915690368</id><published>2008-02-24T23:09:00.000-08:00</published><updated>2008-02-24T23:35:48.838-08:00</updated><title type='text'>A better killall and such</title><content type='html'>Didn't you sometimes wish you had a 'superkill'; a kill that kills all processes with a certain text in it. Killall is supposed to do that, but actually never does, as you have to type the complete command which is a pain. So I usually type:&lt;br /&gt;&lt;br /&gt;ps auxw|grep -i apache|awk '{print $2}'|xargs kill -9&lt;br /&gt;&lt;br /&gt;in this case killing Apache (1 and 2). &lt;br /&gt;&lt;br /&gt;To make life easier, as a regular part of my Debian and Ubuntu installs, I now have the command 'sk' (superkill) in /usr/sbin/sk;&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;ps uaxw|grep -i $1|grep -v $0|grep -v grep|awk '{print $2}'|xargs kill -9&lt;br /&gt;&lt;br /&gt;allowing me to run;&lt;br /&gt;&lt;br /&gt;sk apache&lt;br /&gt;&lt;br /&gt;and gone it is.&lt;br /&gt;&lt;br /&gt;Now that I am writing this anyway; here is another missing command :)&lt;br /&gt;&lt;br /&gt;find /some/directory -maxdepth 1 -type f -mtime +2 -exec rm {} \;&lt;br /&gt;&lt;br /&gt;Into a file /usr/sbin/ro; &lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;find $1 -maxdepth 1 -type f -mtime +$2 -exec rm {} \;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-1486353920915690368?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/1486353920915690368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/1486353920915690368'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/02/better-killall.html' title='A better killall and such'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-341656389492530100</id><published>2008-01-07T07:30:00.000-08:00</published><updated>2008-01-07T07:45:46.848-08:00</updated><title type='text'>Talking to SMTP / Mail via telnet to diagnoze mail problems on a server</title><content type='html'>Mailserver diagnoses can be tricky: I personally find the easiest way to do it still using telnet in combination with the server logs to find out what exactly is wrong. &lt;br /&gt;&lt;br /&gt;It is very easy to do: &lt;br /&gt;&lt;br /&gt;telnet thehost.com 25&lt;br /&gt;&lt;br /&gt;helo: myhost.com&lt;br /&gt;mail from: me@myhost.com&lt;br /&gt;rcpt to: someone@thehost.com&lt;br /&gt;data&lt;br /&gt;&lt;br /&gt;... type some data ...&lt;br /&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;quit&lt;br /&gt;&lt;br /&gt;That is all; it will help to exactly determine where it goes wrong.&lt;br /&gt;&lt;br /&gt;The case we had today; &lt;br /&gt;&lt;br /&gt;- postfix didn't send mail ; it gave connection refused&lt;br /&gt;- thoughts; firewall, network, dns etc.&lt;br /&gt;- we tried the above and it worked fine, meaning postfix was the one refusing, not the network/firewall etc&lt;br /&gt;- we fixed the postfix config and all was fine&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-341656389492530100?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/341656389492530100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/341656389492530100'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/01/talking-to-smtp-mail-via-telnet-to.html' title='Talking to SMTP / Mail via telnet to diagnoze mail problems on a server'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-4529875920681623462</id><published>2008-01-06T08:30:00.000-08:00</published><updated>2008-01-06T08:36:04.350-08:00</updated><title type='text'>PHP Posting to ASP.NET (ASPX) pages / sites</title><content type='html'>If you want to post anything (for instance a login/password), you need to take the viewstate in order to be able to post anything to any aspx page, so request the page for the first time, in the same session: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  $ch = curl_init();&lt;br /&gt;&lt;br /&gt;  curl_setopt($ch, CURLOPT_URL, $login_url);&lt;br /&gt;  curl_setopt($ch, CURLOPT_HEADER, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);&lt;br /&gt;  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');&lt;br /&gt;  curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');&lt;br /&gt;  curl_setopt($ch, CURLOPT_POST, 0);&lt;br /&gt;  curl_setopt($ch, CURLOPT_POSTFIELDS, array());&lt;br /&gt;  $data = curl_exec($ch);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then you collect the viewstate;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  $vars = array("login"=&gt;$user,&lt;br /&gt;                "password"=&gt;$pass);&lt;br /&gt;&lt;br /&gt;  $i = strpos($data, "__VIEWSTATE");&lt;br /&gt;  $i = strpos($data, "value=", $i);&lt;br /&gt;  $i += 7;&lt;br /&gt;  $j = strpos($data, "\"", $i+1);&lt;br /&gt;  $viewstate = substr($data, $i, $j-$i);&lt;br /&gt;  $vars['__VIEWSTATE'] = $viewstate;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;After that you can safely login to the site; &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  curl_setopt($ch, CURLOPT_URL, $login_url);&lt;br /&gt;  curl_setopt($ch, CURLOPT_HEADER, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);&lt;br /&gt;  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');&lt;br /&gt;  curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');&lt;br /&gt;  curl_setopt($ch, CURLOPT_POST, 1);&lt;br /&gt;  curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);&lt;br /&gt;  $data = curl_exec($ch)&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-4529875920681623462?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/4529875920681623462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/4529875920681623462'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2008/01/php-posting-to-aspnet-aspx-pages-sites.html' title='PHP Posting to ASP.NET (ASPX) pages / sites'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry><entry><id>tag:blogger.com,1999:blog-9974736.post-6831725003542785957</id><published>2007-12-24T11:11:00.000-08:00</published><updated>2007-12-24T11:15:44.271-08:00</updated><title type='text'>Analyzing MySQL usage; finding and fixing bottlenecks</title><content type='html'>MyTop and Mtop are nice tools to analyze MySQL load and queries, however long running systems require another system, so I present a simple script to analyze longer running multi user databases for abusers and bottlenecks. The code is very easy to alter to retrieve other stats. &lt;br /&gt;Otherwise you can always mail me to fix it for what you might need.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;while(1) {&lt;br /&gt; # load all previous data, if any&lt;br /&gt; %users = (); &lt;br /&gt; if (-f "./sql.log") {&lt;br /&gt;  open(F, "./sql.log"); &lt;br /&gt;  while(&lt;F&gt;) {&lt;br /&gt;   chomp; &lt;br /&gt;   # user no_queries tot_length&lt;br /&gt;   /(.*?)\ (.*?)\ (.*)/;&lt;br /&gt;   $users{$1} = "$2 $3";&lt;br /&gt;  }&lt;br /&gt;  close F;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @p = `mysql -u yyy --password=xxx --execute='show full processlist'`;&lt;br /&gt; for($i=3;$i&amp;lt;scalar(@p)-1;$i++) {&lt;br /&gt;  $r = $p[$i]; &lt;br /&gt;  chomp($r); &lt;br /&gt;  @cols = split(/\t/, $r);&lt;br /&gt;&lt;br /&gt;  next if $cols[4] eq "Sleep";&lt;br /&gt;&lt;br /&gt;  $q = ""; &lt;br /&gt;  for($j=7;$j&amp;lt;scalar(@cols);$j++) {&lt;br /&gt;   $q .= $cols[$j]." ";&lt;br /&gt;  }&lt;br /&gt;  next if $q=~/show full processlist/;&lt;br /&gt;  next if $q eq "NULL";&lt;br /&gt;&lt;br /&gt;  $u = $cols[1];  &lt;br /&gt;  $l = $cols[5];&lt;br /&gt;&lt;br /&gt;  $res = "";&lt;br /&gt;  if (!$users{$u}) {&lt;br /&gt;   $res = "1 $l";&lt;br /&gt;  } else {&lt;br /&gt;   $res = $users{$u}; &lt;br /&gt;   $res =~ /(.*?)\ (.*)/; &lt;br /&gt;   $l += $2;&lt;br /&gt;   $t = $1 + 1;&lt;br /&gt;   $res = "$t $l";&lt;br /&gt;  }&lt;br /&gt;  $users{$u} = $res;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; open(F, "&gt;./sql.log");&lt;br /&gt; foreach(keys(%users)) {&lt;br /&gt;  $res = $users{$_};&lt;br /&gt;  print F "$_ $res\n";&lt;br /&gt; }&lt;br /&gt; close F;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9974736-6831725003542785957?l=brainfish-eat-fishbrain.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/6831725003542785957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9974736/posts/default/6831725003542785957'/><link rel='alternate' type='text/html' href='http://brainfish-eat-fishbrain.blogspot.com/2007/12/analyzing-mysql-usage-finding-and.html' title='Analyzing MySQL usage; finding and fixing bottlenecks'/><author><name>tycho</name><uri>http://www.blogger.com/profile/03157313039640117008</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='14772369638459340151'/></author></entry></feed>