Monday, March 23, 2009, 02:12 PM - Tutorials
Hi there,Very busy schedule since last few days as was busy in hand over of tasks as I am leaving my old organization.
Currently, I am planning to write complete howtos / guide about "Security Assessment / Security Audit" if I could manage some time.
This was just to ping again.
More to come,
Aniruddha




( 2.9 / 303 )
Sunday, September 2, 2007, 11:49 AM - Tutorials
Hi,Here is a simple guide to harden redhat / centos linux
Although its not based on hard and fast rules, you will get some
good hints how its done.
I hope it helps someone.
Thanks,
Aniruddha
Tuesday, July 24, 2007, 12:12 PM - Tutorials
This is in ref. with "A MIMEDefang filter to block spam, mail forging, adding boilerplates, smtp dictionary attacks" Few Things that I had not mentioned clearly in the above post:
The filter DOES accept the first spam mail from any ip address, adds boilerplate ("the ip has got banned please contact admin in case of any issues...") and then sends it to the recipient.
Then it adds the ip into the database and the next time when spammer tries to connect to the server, it simply rejects the spammer.
This is the default behavior so that false alert should not ban the genuine user forever. This way the filter will become more and more mature as and when new ip addresses are banned.
But yes, If you want this action to be changed to:
"Discarding the first spam message from certain ip address too"
then I would suggest following change in the code:
------------------------Original code snippet---------
my($hits, $req, $names, $report) = spam_assassin_check();
action_change_header("X-Spam-Score","$hits :: $names ");
if (($hits > 10 ) && (!&ISMYIP($RelayAddr))) {
my $dbh = DB_CONNECT();
my $ath = $dbh->prepare(qq{insert into `blockedip` values('$RelayAddr')});
$ath->execute();
$ath->finish();
$dbh->disconnect();
$BOILit = "This is a Spammer $RelayAddr so it has got banned. Contact admin if any issues " ;
}
append_text_boilerplate($entity, "$BOILit ", 0);
}
# DO NOT delete the next line, or Perl will complain.
1;
------------------------Suggested code snippet---------
my($hits, $req, $names, $report) = spam_assassin_check();
action_change_header("X-Spam-Score","$hits :: $names ");
if (($hits > 10 ) && (!&ISMYIP($RelayAddr))) {
my $dbh = DB_CONNECT();
my $ath = $dbh->prepare(qq{insert into `blockedip` values('$RelayAddr')});
$ath->execute();
$ath->finish();
$dbh->disconnect();
$BOILit = "SpAmMeR";
}
if ($BOILit ne "SpAmMeR") {
append_text_boilerplate($entity, "$BOILit ", 0);
} else {
action_discard();
}
}
# DO NOT delete the next line, or Perl will complain.
1;
############################
#CODE ENDED HERE
############################
Few more things that users keep on asking me:
1) About Boiler Plate Data:
These boiler plates are to be added manually and they are not added automatically.
Each mail account can have his /her own boiler plate.
Don't use this as a signature because this costs cpu power and other resources.
This is to be added as per the "Organizational role played by the mail account holder". Thats defined by the organizational policies in most cases.
2) Currently there are no tools to add or remove mail ids, blocked ips, boiler plates or for any data manipulation in the database.
3) About further developments of this basic simple filter:
Hmmm..
I am seriously thinking of creating A GPL based complete spam protection suit. Which would use:
i) SpamAssassin
ii) MIMEDefang
iii) Apache for web based administration
iv) MySQL
v) PHP as a development language for web based control panel.
vi) A MIMEDefang filter to bring i, ii, iv and sendmail together.
AND
vii) Most Important SENDMAIL!
I would appreciate if some one can suggest me features that should be included.
Hey, but I have not promised that I will be doing all of the above
- Aniruddha Thombre
<a href="http://www.aniruddhas.com/" target="_blank">- Aniruddha Thombre</a>
Friday, July 20, 2007, 06:52 AM - Tutorials
MySQL Replication made simple Edit /etc/my.cnf on Primary / Master MySQL server from which you want to replicate the data
to add following lines:
------------------------------------------------------
#Name of Binary log File Which has to be provided to slave server too.
log-bin=mysql-bin.log
#Name of the database which you want to replicate or the one which you dont want to be replicated.
binlog-do-db=replicatethisdb
binlog-ignore-db=dontreplicatedb
#Unique server id (Unique among all replication master / slaves)
server-id=1
------------------------------------------------------
---------------------------------------------------------------------
Sample MySQL Configuration file On the Master:
/etc/my.cnf
---------------------------------------------------------------------
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=mysql-bin.log
binlog-do-db=replicatethisdb
binlog-ignore-db=mysql
server-id=1
[mysql.server]
user=mysql
basedir=/var/lib
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
---------------------------------------------------------------------
restart mysql on server
Connect to the mysql server:-
mysql -u root -p
Execute following:-
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'remote.hostname' IDENTIFIED BY '<some_password>';
FLUSH TABLES WITH READ LOCK;
#You need to say *.* not replicatethisdb.* as REPLICATION is an administrative right.
SHOW MASTER STATUS;
+------------------+----------+----------------+------------------+#Record filename and Position in above table.
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+-----------------+------------------+
| mysql-bin.000001 | 98 | replicatethisdb | mysql |
+------------------+----------+-----------------+------------------+
on slave edit in /etc/my.cnf to add :
server-id=2
master-host = my.masterhostip.or.name
master-user = slave
master-password = some_password
replicate-do-db = replicatethisdb
log-warnings
restart mysqld on slave
On slave connect to mysql:
mysql -u root -p
#Stop slave if it is working with:
STOP SLAVE;
#Execute following:
CHANGE MASTER TO MASTER_HOST='my.masterhostip.or.name', MASTER_USER='slave', MASTER_PASSWORD='some_password', MASTER_LOG_FILE='recorded_log_file_name', MASTER_LOG_POS=recorded_log_position;
# that becomes following in our case:
CHANGE MASTER TO MASTER_HOST='my.masterhostip.or.name', MASTER_USER='slave', MASTER_PASSWORD='some_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;
#Restart both mysql servers to check if it is working.
#To check that fire up following queries:
#This is to be executed on the master server
SHOW MASTER STATUS;
#This is to be executed on the slave server
SHOW SLAVE STATUS;
#Record log file names and positions and check if both are matching. It should, if it is working.
Thats it! We have got MySQL Replication working!
Isn't that "MySQL Replication made simple" ?
- Aniruddha Thombre
Other Tutorials on aniruddhas.com
Tuesday, June 12, 2007, 06:42 AM - Tutorials
So, Whats MyDNS?Its a DNS server.
For further details on how to install and configure it, you may have to visit:-
http://mydns.bboy.net/
or also mysql and postgresql's respective home pages.
We are just going to discuss the features and benefits of MyDNS
MyDNS:- MySQL (Also PostgreSQL) backed DNS server
Features:-
"stability, security, interoperability, and speed" as the author says!
No need to reload dns server after any change in any or all zones.
Speed is not affected no matter how many zones we have, and how many entries a zone has.
As it is backed up by MySQL /PostgreSQL we may load balance / mirror the databases.
The structure may look like this:-
1) Master DNS server
-- has a database holding all required zone info
-- that database is allowed to be replicated on slaves
-- gets zone info from zone files located on respective servers
-- we can use tools such as myphp or admin scripts for myDNS to change the settings for individual or all files manually whenever required
-- We can also use API's for control panels to directly modify the databases on DNS servers If any control panels such as plesk / cpanel etc are used.
-- Developing a simple application for a database with just two tables is not difficult
-- we can have completely different database server setup if required
2) Slave DNS server
-- database is replicated from the master dns server, every 60 seconds or so
If any thing goes wrong with master dns server (such as major hardware failures) we may immediately add master dns server's ip to the slave and stop replication process.
Homepage for MyDNS is located here:-
http://mydns.bboy.net/
- Aniruddha Thombre
Friday, May 25, 2007, 08:56 AM - Tutorials
Hi Everyone,Here is a simple MIMEDefang filter which tries to defend from spam
This filter is supposed to be used where:-
There are multiple servers / hosts on behalf of which this mail server accepts the mails.
Setup:-
mail.example.com (sendmail server with mimedefang): 10.0.0.1
mimedefang on mail.example.com considers 10.0.0.1, 10.0.0.2 as own ip and everything else is the world.
mimedefang on Server needs mysql running which holds database 'defang' (user defang , pass dbpassword)
Features of the first filter:-
filter allows own network to do anything (127.0.0.1 / 10.0.0.1, 10.0.0.7 ) whats with smtp norms
filter blocks ip address if someone tries sending mails to nonexistent users.
filter blocks ip address if someone tries mail forging by own mail ids from other ip addresses.
filter accepts mails for users which exist in database.
filter rejects every command from the ip which is listed as blocked.
filter blocks ip address if someone sends spam scoring more than 10 on spamassassin. Then adds a boiler plate to reciving user that the ip has been blocked and contact admin in case of any issues.
user defined boilerplates can be added (or may be domain specific if needed).
So this filter is supposed to be used to act against:-
spammers and spam, a filter against mail forging, a filter to add boilerplates, a filter to act against smtp dictionary attacks.
#############################################################
database structure:-
Database name:- "defang"
+------------------+
| Tables_in_defang |
+------------------+
| blockedip |
| mailnames |
+------------------+
mysql> select * from blockedip;
+--------------+
| ipaddress |
+--------------+
| 10.0.0.9 |
+--------------+
mysql> select * from mailnames;
+-------------------------------------+-----------------+
| mailname | boilerplate |
+-------------------------------------+-----------------+
| aniruddha@example.com | Zakkasss....... |
+-------------------------------------+-----------------+
code begins here:-
#############################################################
detect_and_load_perl_modules();
sub DB_CONNECT() {
use DBI;
my $dsn = 'DBI:mysql:defang:localhost';
my $db_user_name = 'defang';
my $db_password = 'dbpassword';
my $dbh = DBI->connect($dsn, $db_user_name, $db_password);
return $dbh;
}
sub ISMYIP($) {
my ($ISITOUR) = @_;
my @NETWORK = ('127.0.0.1' , '10.0.0.1' , '10.0.0.7');
foreach my $ADDRESS (@NETWORK) {
if ( $ISITOUR eq $ADDRESS) {
return true;
}
}
}
sub filter_relay($$$) {
my ($hostip, $hostname, $helo) = @_;
{
if ( &ISMYIP($hostip) ) {
return ('CONTINUE', "You are allowed $hostip");
}
my $dbh = DB_CONNECT() or return ('CONTINUE', "ok");
my $sth = $dbh->prepare(qq{select `ipaddress` from `blockedip` where `ipaddress` = '$hostip'});
$sth->execute();
($ipexists) = $sth->fetchrow_array();
$sth->finish();
$dbh->disconnect();
if ($hostip eq $ipexists) {
return ('REJECT', "Go away you spammer!");
}
return ('CONTINUE', "ok");
}
}
sub filter_sender ($$$$) {
my ($sender, $hostip, $hostname, $helo ) = @_;
if ( &ISMYIP($hostip) ) {
return ('CONTINUE', "You are allowed $hostip");
}
my $dbh = DB_CONNECT() or return ('CONTINUE', "ok yup");
my $sth = $dbh->prepare(qq{select `ipaddress` from `blockedip` where `ipaddress` = '$hostip'});
$sth->execute();
($ipexists) = $sth->fetchrow_array();
$sth->finish();
#$dbh->disconnect();
if ($hostip eq $ipexists) {
$dbh->disconnect();
return ('REJECT', "Did you just decide to spam me?");
}
my $sndr = substr("$Sender",1,(length($Sender) - 2 ));
my $sth = $dbh->prepare(qq{select `mailname` from `mailnames` where `mailname` = '$sndr'});
$sth->execute();
($exists) = $sth->fetchrow_array();
$sth->finish();
if ( ($sndr = $exists) && (!&ISMYIP($RelayAddr) ) ) {
my $ath = $dbh->prepare(qq{insert into `blockedip` values('$RelayAddr')});
$ath->execute();
$ath->finish();
$dbh->disconnect();
return ('REJECT',"Go find someone else you forger");
}
return ('CONTINUE', "ok done");
}
sub filter_recipient ($$$$$$) {
my ($recipient, $sender, $ip, $hostname, $first, $helo) = @_;
my $dbh = DB_CONNECT() or return ('CONTINUE', "ok");
my $rcp = substr("@Recipients",1,(length(@Recipients) - 2 ));
my $sth = $dbh->prepare(qq{select `mailname` from `mailnames` where `mailname` = '$rcp'});
$sth->execute();
($exists) = $sth->fetchrow_array();
$sth->finish();
my $isth = $dbh->prepare(qq{select `ipaddress` from `blockedip` where `ipaddress` = '$ip'});
$isth->execute();
($iexists) = $isth->fetchrow_array();
$isth->finish();
if ($ip eq $iexists) {
$dbh->disconnect();
if (&ISMYIP($ip)) {
return ('CONTINUE', "ok");
}
return ('REJECT', "Dont try to be wise");
}
if ($rcp eq $exists) {
$dbh->disconnect();
return ('CONTINUE', "ok");
}
if ( &ISMYIP($ip)) {
return ('REJECT', "$rcp $recipient @Recipients ! I really don't know this mail id!");
}
my $ath = $dbh->prepare(qq{insert into `blockedip` values('$ip')});
$ath->execute();
$ath->finish();
$dbh->disconnect();
return ('REJECT', "$recipient! I really don't know this mail id!");
}
sub filter_end ($) {
my($entity) = @_;
return if message_rejected();
sub boilit {
my $ABC = substr("$Sender",1,(length($Sender) - 2 ));
my $dbh = DB_CONNECT();
my $sth = $dbh->prepare(qq{select `boilerplate` from `mailnames` where `mailname` = '$ABC'});
$sth->execute();
($BOILER) = $sth->fetchrow_array();
$sth->finish();
$dbh->disconnect();
if ($BOILER eq "") {
return $ABC;
}
return $BOILER;
}
my $BOILit = &boilit();
my($hits, $req, $names, $report) = spam_assassin_check();
action_change_header("X-Spam-Score","$hits :: $names ");
if (($hits > 10 ) && (!&ISMYIP($RelayAddr))) {
my $dbh = DB_CONNECT();
my $ath = $dbh->prepare(qq{insert into `blockedip` values('$RelayAddr')});
$ath->execute();
$ath->finish();
$dbh->disconnect();
$BOILit = "This is a Spammer $RelayAddr so it has got banned. Contact admin if any issues " ;
}
append_text_boilerplate($entity, "$BOILit ", 0);
}
# DO NOT delete the next line, or Perl will complain.
1;
###############################################
# Code ends here
###############################################
This is a very simple filter but still it gives a glimpse at the power of MIMEDefang
Please Visit:- http://www.mimedefang.org/ for further details.
Hope, someone gets benefited from this post
Let me know if somebody has any suggestions, improvements, or requires any filters developed for.
- Aniruddha Thombre

Avatar






