2010年2月26日 星期五

[轉錄][Linux] 防 ssh 暴力攻擊 使用iptables & shell @ CentOS

之前看到的, 紀錄一下, 以下內容為全部引用(稍微排版了一下)...
原文標題: [Linux] 防 ssh 暴力攻擊 使用iptables & shell @ CentOS
原文作者: phptw  
發表日期: 2008-06-30 22:06
原始連結: http://blog.phptw.idv.tw/read-174.html

原則上 ssh port 能不要全部開啟事最好的,如果一定要開啟的話,必需要作些防護措施,
port 22 一旦開啟後最容易遇到的就是會有人不斷的try密碼

設計原理:
   1. 抵擋 ssh 暴力攻擊
   2. 如果連續攻擊3次以上則抵擋
   3. 利用 TCP-Wrapper 偵測是否有登入失敗 ,有失敗才執行shell 

mkdir /etc/firewall/
touch /etc/firewall/sshd.sh
chmod 755 /etc/firewall/sshd.sh
vi /etc/firewall/sshd.sh
寫入以下資料

#!/bin/bash
# 檔案存放的路徑
basedir="/etc/firewall"

# log 存放的地方
sshlog="/var/log/auth.log"

# mail for
mailfor="root"

# 登入錯誤訊息
faildMsg="sshd.*Failed password"
faildMsgInvalid="sshd.*Failed password for invalid user"

# 登入幾次失敗 就擋掉
loginCountFail=3

# 計算前 XXXX 行是否有登入失敗的狀況
failcount=`/usr/bin/tail -n 50 "$sshlog" | /bin/grep "$faildMsg" | wc -l`

#cat "$sshlog" | grep "sshd.*Failed password for" | grep -v "invalid" | cut -d " " -f11
#cat "$sshlog" | grep "sshd.*Failed password for invalid user" | cut -d " " -f13

# 如果有登入失敗的話
if [ "$failcount" -gt "0" ]; then

   # 建立 登入失敗 暫存檔
   #cat /var/log/auth.log | grep "sshd.*Failed password for" | grep -v "invalid"
   cat "$sshlog" | grep "sshd.*Failed password for" | grep -v "invalid" > /tmp/ssh_tmp.log
   #cat /var/log/auth.log | grep "sshd.*Failed password for" | grep -v "invalid"
   cat "$sshlog" | grep "sshd.*Failed password for invalid user" > /tmp/ssh_tmp2.log

   # 建立 登入失敗 IP 暫存檔
   #cat "$sshlog" | grep "$faildMsg" | cut -d " " -f13 | sort | uniq > /tmp/ssh_ip_tmp.log
   cat /tmp/ssh_tmp.log | cut -d " " -f11 > /tmp/ssh_ip_tmp.log
   cat /tmp/ssh_tmp2.log | cut -d " " -f13 >> /tmp/ssh_ip_tmp.log

   # 取得要封鎖的IP位址
   #blockip=`cat /tmp/ssh_ip_tmp.log`
   blockip=`cat /tmp/ssh_ip_tmp.log | sort | uniq`

   # iptables中,找出定義的ruleexistchar中的ip。
   #iptables -L INPUT -n | grep "tcp dpt:22" | grep "DROP" | awk '{print $4}' | sort | uniq
   ruleexistip=`iptables -L INPUT -n | grep "tcp dpt:22" | grep "DROP" | awk '{print $4}' | sort | uniq`

   blacklist=`cat "$basedir"/ssd_blacklist_d`
   for ip in $blacklist
   do
 `iptables -D INPUT -p TCP -s $ip  --dport 22 -j DROP` > /dev/null
   done

   rm -rf "$basedir"/ssd_blacklist_d

   # 利用 for 迴圈去跑 drop IP
   for ip in $blockip
   do

 # 計算此IP登入幾次失敗
 count=`cat /tmp/ssh_ip_tmp.log | grep "$ip" | wc -l`

 # 如果登入失敗次數大於 預設值 則執行  drop
 if [ "$count" -gt "$loginCountFail" ] ; then
    #echo $ip  $count
    # 如果從secure找出的ip已存在於iptables,就不需要加這條rule了。
    if [ "$ip" = "$ruleexistip" ]; then
    :
    else
  `iptables -I INPUT -p TCP -s $ip  --dport 22 -j DROP`
    fi
    # if [ "$ip" = "$ruleexistip" ];

    # 建立黑名單
    echo "$ip" >> "$basedir"/ssd_blacklist_d
    cat "$basedir"/ssd_blacklist_d | sort | uniq > "$basedir"/ssd_blacklist_d

 fi
 # if [ "$count" -gt "$loginCountFail"] ;

   done
   # for loop done

   # 刪除暫存檔
   rm -rf /tmp/ssh*.log

   mail -s "ssh hacker 抵擋的IP位址" $mailfor < "$basedir"/ssd_blacklist_d
  
fi
# if [ "$failcount" -gt "0" ];

然後在

vi /etc/hosts.allow

加入 sshd : ALL : spawn /etc/firewall/sshd.sh

參考資料:
    * http://www.andowson.com/posts/list/33.page
    * http://ssorc.tw/rewrite.php/read-93.html

2010年2月20日 星期六

用PHP備份MySQL

很久以前寫的, 筆記一下...

/** 
*    File: backup_mysql.php
* Purpose: 資料庫備份程式, 包括資料庫schema
*   Usage: 1.修改資料庫連線變數
*          2.修改備份類型: full完整備份/data資料備份,
*            full:會備份所有資料庫,
*            data:不備份information_schema,mysql,test三個資料庫
*          3.直接執行(CLI/Browser),
*            將在同目錄下, 產生'mysql_YYYY-MM-DD.sql'的備份檔案
*  Modify: 2008-03-17
*/

//
// 資料庫連線
//
$DB_NAME = YOUR_DB_NAME;  // 主機名稱
$DB_USER = YORU_DB_USER;  // 資料庫使用者名稱
$DB_PASS = YOUR_DB_PASS;  // 資料庫使用者密碼

//
// 備份設定
//
$BACKUP_TYPE = "data";   // 備份類型: full完整備份/data資料備份
$IS_DISPLAY  = "0";      // 顯示SQL語法於螢幕?  1:是/0:否

// 判斷是由CLI執行或是Browser執行
if (isset($_SERVER['HTTP_USER_AGENT'])) {
  echo "<html><head>\n<meta http-equiv=\"Content-Type\" 
        content=\"text/html; charset=UTF-8\">\n</head><body>\n";
  $NEW_LINE = "<br>";
  $TRIPLE_NEW_LINE = "<br><br><br>";
} else {
  $NEW_LINE = "\n";
  $TRIPLE_NEW_LINE = "\n\n\n";
}

//
// 開始進行備份
//
// 1.建立備份檔案
$fp = fopen(getcwd()."/mysql_" . date("Y-m-d") . ".sql" ,"w+");

// 2.資料庫連線
$link = mysql_connect($DB_NAME, $DB_USER, $DB_PASS);
$db_list = mysql_list_dbs($link);

// SQL語法字串
$sql_str = "";

// 3.將每一資料庫備份
while ($obj = mysql_fetch_object($db_list)) {
  
  // 建立資料庫的SQL語法
  mysql_select_db($obj->Database);

  //
  // 判斷備份類型
  //
  if (($BACKUP_TYPE == "full") ||           // full完整備份
      ($BACKUP_TYPE == "data") &&           // data資料備份
      ("information_schema" != $obj->Database) && 
      ("mysql" != $obj->Database) && 
      ("test"  != $obj->Database)) {
    
    $sql_str = "CREATE DATABASE `$obj->Database` 
                DEFAULT CHARACTER SET utf8;\n";
    
    fputs($fp, $sql_str);               // 寫入到檔案
    if ($IS_DISPLAY) {
      echo $sql_str.$TRIPLE_NEW_LINE;   // 顯示在螢幕
    }
    
    // 讀出資料表名稱
    $show_table_result = 
      mysql_query("SHOW TABLES FROM ". $obj->Database);
    
    while ($table = mysql_fetch_row($show_table_result)) {
      
      $show_fields_result = 
      mysql_query("SHOW COLUMNS FROM ". $table[0]);
      
      //
      // Start 建立資料表的SQL
      //
      $sql_str = "CREATE TABLE `$table[0]` (\n";
      
      $sql_field = array();
      
      while($field_arr = mysql_fetch_assoc($show_fields_result)){
        
        // is NULL?
        switch ($field_arr['Null']) {
          case "NO":
            $sql_field['Null'] = " NOT NULL";
          break;
          
          default:
            $sql_field['Null'] = "";
          break;
        }      
        
        // is primary key/unique key?
        switch ($field_arr['Key']) {
          case "PRI":
            $sql_field['Key'] = " primary key";
          break;
          
          case "UNI":
            $sql_field['Key'] = " unique key";
          break;
          
          default:
            $sql_field['Key'] = "";
          break;
        }
        
        // default value
         switch ($field_arr['Default']) {
          case "":
            $sql_field['Default'] = "";
          break;
          
          default:
            $sql_field['Default'] = " default " .
                                    $field_arr['Default'];
          break;
        }         
        
        // auto increment?
         switch ($field_arr['Extra']) {
          case "auto_increment";
            $sql_field['Extra'] = " auto_increment";
          break;
          
          default:
            $sql_field['Extra'] = "";
          break;
        }  
        
        $sql_str .= "`" . $field_arr['Field'] . "` " . 
                          $field_arr['Type']  . 
                          $sql_field['Null']  . 
                          $sql_field['Key']   . 
                          $sql_field['Default'] . 
                          $sql_field['Extra'] . ", \n";
      }
      
      $sql_str = substr($sql_str, 0, strlen($sql_str)-3);
      
      $sql_str .= "\n) MYISAM DEFAULT CHARSET=utf8 
                  COLLATE=utf8_unicode_ci;\n\n";
      
      
      fputs($fp, $sql_str);               // 寫入到檔案
      if ($IS_DISPLAY) {
        echo $sql_str.$TRIPLE_NEW_LINE;   // 顯示在螢幕
      }
      //
      // End 建立資料表的SQL
      //
  
      // 以utf-8連線MySQL
      //mysql_query("SET NAMES 'utf8'");
      //mysql_query("SET CHARACTER_SET_CLIENT=utf8");
      //mysql_query("SET CHARACTER_SET_RESULTS=utf8");

      // 根據每個資料表將欄位讀出
      $result = mysql_query("SELECT * FROM ". $table[0]);
      
      while ($field_arr = mysql_fetch_row($result)) {
      
        $sql_str = "INSERT INTO `".$table[0]."` VALUES (";
        
        foreach ($field_arr as $field) {
          $sql_str .= "'".$field."', ";
        }
        
        $sql_str = substr($sql_str, 0, strlen($sql_str)-2);
        
        $sql_str .= ");\n";
        
        fputs($fp, $sql_str);             // 寫入到檔案
        if ($IS_DISPLAY) {
          echo $sql_str.$NEW_LINE;        // 顯示在螢幕
        }  
      }
      
      fputs($fp, "\n\n");                 // 寫入到檔案
      if ($IS_DISPLAY) {
        echo $TRIPLE_NEW_LINE;            // 顯示在螢幕
      }
    }
    // End while (fetch_row)
  }
  // End if (BACKUP_TYPE)
} 
// End while (obj)
//
// 結束備份
//


// 4.關檔
fclose($fp);  

echo '<h1>備份完成!!</h1>' . "\n";

2010年2月19日 星期五

Facebook Application Development Reference

之前寫了一些Facebook Application, 包括了Facebook Connect等技術都有用到, 但是Facebook的API改版頗快, 所以之前閱讀的書籍可能也有些過時了, 以下列出供有緣人參考...
因此有志於開發此類應用程式的人一定要訂閱它的RSS以追蹤最新的訊息,

有時間再把開發心得與技術補上吧...

PHPGMailer

之前需要寫個GMail的寄信程式, 發現已經有人寫好PHPGMailer的class了, 就備份一下吧,

對了, Google Docs現在可以上傳任何格式的檔案了, 真是方便阿 : )