2010年3月10日 星期三

[轉錄] SSH Tunnel

最近有透過SSH Tunnel瀏覽網頁的需求, 剛好看到這篇, 寫的簡單易懂就備份起來了... 感謝A0933305


update (2010-07-02)

若是在*nix上, 則使用先和ssh server建立ssh tunnel後,將所有從指定port出去的封包都導到ssh server
語法:
$ ssh -D LOCAL_PORT SSH_SERVER_IP
例:
$ ssh -D 8888 192.168.1.1
使用:
所有從本機3128 port出去的連線都會被導到192.168.1.1,此時在firefox中設定socks主機為127.0.0.1 8888 port,就可以用firefox透過192.168.1.1連到外部網路

參考資料:
[筆記]被防火牆擋住出不去? ssh tunnel讓你鑽洞溜出去

2010年3月9日 星期二

[轉貼][轉貼] 上傳檔案前, JavaScript檢查檔案格式, 大小

原文標題: [SCript] [轉貼]上傳檔案前,JavaScript檢查檔案格式、大小
原文作者: topcat
發表日期: 2009-02-20 14:14
原始連結: http://itgroup.blueshop.com.tw/topcat/aspx?n=convew&i=5684

之前看到的, 紀錄一下, 程式部份為全部引用(稍微排版了一下)...
在檔案送出前以JavaScript檢查檔案格式與大小在不同瀏覽器上有稍微的不同, 目前測的結果是IE6/IE7可以... 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=big5"> 
<title>上傳</title> 
</head> 
<body> 
<form ACTION="upload.asp" METHOD="POST" name="FileForm" enctype="multipart/form-data"> 
圖片: <input type="file" name="file1" size="20" id="file1"> 
<input type="button" value="確定上傳" onClick="checkFile()"> 
</form> 
</body> 
</html> 
<script language="JavaScript"> 

//這裡控制要檢查的項目,true表示要檢查,false表示不檢查 
var isCheckImageType = true;   //是否檢查圖片副檔名 
var isCheckImageWidth = true;  //是否檢查圖片寬度 
var isCheckImageHeight = true; //是否檢查圖片高度 
var isCheckImageSize = true;   //是否檢查圖片檔案大小 

var ImageSizeLimit = 100000;   //上傳上限,單位:byte 
var ImageWidthLimit = 1200;    //圖片寬度上限 
var ImageHeightLimit = 1000;   //圖片高度上限 

function checkFile() { 
 var f = document.FileForm; 
 var re = /\.(jpg|gif)$/i;  //允許的圖片副檔名 
 if (isCheckImageType && !re.test(f.file1.value)) { 
   alert("只允許上傳JPG或GIF影像檔"); 
 } else { 
   var img = new Image(); 
   img.onload = checkImage; 
   img.src = f.file1.value; 
 } 
} 
function checkImage() { 
 if (isCheckImageWidth && this.width > ImageWidthLimit) { 
   showMessage('寬度','px',this.width,ImageWidthLimit); 
 } else if(isCheckImageHeight && this.height > ImageHeightLimit) { 
   showMessage('高度','px',this.height,ImageHeightLimit); 
 } else if (isCheckImageSize && this.fileSize > ImageSizeLimit) { 
   showMessage('檔案大小','kb',this.fileSize/1000,ImageSizeLimit/1000);   
 } else { 
   document.FileForm.submit(); 
 } 
} 
function showMessage(kind,unit,real,limit) { 
 var msg = "您所選擇的圖片kind為 real unit\n超過了上傳上限 limit unit\n不允許上傳!" 
 alert(msg.replace(/kind/,kind).replace(/unit/g,unit).replace(/real/,real).replace(/limit/,limit)); 
} 
</script>

[Embedded] The GNU configure and build system - Cross Compilation Tools

在做cross compilation的時候, 需要將手邊的程式編譯成可在目標裝置上執行的代碼, 這時候就會需要用到cross compiler中的系統參數了...

根據GCC documentation可以知道
--build: the machine you are building on
--host: the machine you are building for
--target: the machine that GCC will produce code for

翻譯一下就是build就是你現在使用的機器,host就是你編譯好的程序能夠運行的平台,target是編譯程序能夠處理的平台,一般使用在開發工具上

因此如果我們希望在x86環境下編譯一個可以在arm環境中處理mips的gcc,可能會類似 ./configure --build=i386-linux --host=arm-linux --target=mipsel-linux

reference:
* GCC documentation
* GNU Configure中的 build target和host的區別

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現在可以上傳任何格式的檔案了, 真是方便阿 : )