顯示具有 ubuntu 標籤的文章。 顯示所有文章
顯示具有 ubuntu 標籤的文章。 顯示所有文章

2014年9月16日 星期二

SSH 加密技術介紹

來源:http://blog.yam.com/mingrass/article/17327933
相關:[教學] CentOS 6.3 設定 – (1) 基本調效與 SSH 連線
還記得在第十一章介紹過的遠端連線指令 telnet 及 ssh 吧 ! 由於 telnet 在資料傳輸過程的不安全,因此都鼓勵大家使用 ssh。那要提供 SSH 服務來給 Client 端做遠端連線時,當然就要架設 SSH Server 了。

 SSH 可以取代傳統的 r 指令 (rsh、rlogin、rcp)、finger 及 telnet 這一類較不安全的連線工具。使用 SSH (Secure SHell),可讓我們所傳輸的資料都事先經過加密,因此 Client 端可以使用 scp 指令在兩台電腦間很安全的複製資料,也可以使用 sftp 指令來安心的存取 ftp 服務。

SSH 協定的版本
 SSH 協定目前有 SSH1 ( SSH protocol version 1 ) 及 SSH2 ( SSH protocol version 1 ) 兩種版本,當然現在的主流是 SSH2,因為它提供了比 SSH1 更安全的資料傳輸。

 在 SSH 上頭,常見到的加密演算法有 RSA、DSA 及 Diffie-Hellman 等。SSH1 主要是使用 RSA 的加密技術,而 SSH2 除了 RSA 以外,還有 DSA 及 Diffie-Hellman 等等。

SSH 加密流程

SSH1 加密技術
˙ Client 向 SSH Server 的 22 port 做出連線請求。
˙ Server 傳送 public key 給 Client:
關於這個地方,您需先了解什麼是 host key pair 及 server key pair。
host key pair 是指存在於 SSH Server 上的一對公鑰 (host public key) 及私鑰 (host private key)。
server key pair 是指在每次 SSH 服務啟動時,所隨機產生的一對公鑰 (server public key) 及私鑰 (server private key),且這個 server key 預設每小時會更換一次。
而 SSH Server 所回應給 Client 的 public key,就是指 host public key 及 server public key。
˙ Client 端比對 host public key:
Client 端對 SSH Server 所傳送過來的 host public key 進行比對,如果與 ~/.ssh/known_hosts 檔案內容相符,則繼續進行下一步,否則會詢問您是否要接受這個 key,此時輸入 yes 就對了。
當 使用者第一次與 Server 做連線時,由於之前並沒有取得這個 key,因此會詢問您是否要接受 Server 所傳來的 host public key,那萬一先前已做過連線,現在還是看到這個訊息,這就表示 Server 上的 host public key 與 Client 的 known_hosts 比對不符合的結果,比如像 Server 的 SSH 套件重新安裝過後就會有這種情形發生。那萬一您遇到的狀況是在 key 比對不符後,直接拒絕您連線,這該怎麼辦呢 ? 很簡單,只要把 Client 的 ~/.ssh/ 目錄下的 known_hosts 檔刪除後,再與 Server 做連線,以重新取得 host public key 就行了。
˙ Client 隨機產生一個 256 bit 的亂數 (session key):
當第三步驟通過後,Client 隨即產生這個亂數,並使用剛剛從 Server 那裡所得到的那兩把 key 來一起做加密,完成後就傳回給 Server。
˙ Server 使用 private key 來解密。
˙ 爾後就透過這 session key 來作對稱式的加密使用。
˙ Client 端開始進行認證,通過後,SSH 連線正式建立起來。
SSH2 加密技術
˙ Client 向 SSH Server 的 22 port 做出連線請求。
˙ Server 傳送 host public key 給 Client:
在 SSH2 裡,sshd daemon 啟動時,並不會產生 server key,所以只會傳送 host public key 給 Client。
˙ Client 端比對 host public key:
與 SSH1 的做法相同,不再贅述。
˙ 使用 Diffie-Hellman 的演算法來產生 session key,以作為連線加密使用。
˙ Client 端開始進行認證,通過後,SSH 連線正式建立起來。

2014年9月15日 星期一

Linux user group 操作


如何新增一個帳號並同時指定主群組(primary group)

在linux作業系統中,要增加一個使用者也就是新增一個帳號我們一般會下以下指令;
useradd username
所以增加一個my_home帳號就是︰
# useradd my_home
那麼,如果要新增一個帳號同時指定這個帳號的主群組(primary group)該如何下指令呢?如下︰
useradd -g {group-name} username
所以新增一個叫做my_home的帳號並同時指定my_home的主群組為rd則輸入︰
# useradd -g rd my_home
這裡要注意rd這個群組必須是已存在的,要確認rd群組是否存在可以下指令︰
# grep rd /etc/group
如果沒有任何資訊被顯示出來的表示rd群組並不存在,新增rd群組的指令如下︰
# groupadd rd
如此我們就成功新增了使用者my_home並同時指定他的主群組為rd。
如何新增一個帳號並同時指定副群組(secondary group)
那麼,假使我們要新增一個帳號並同時指定他的副群組又該如何設定呢?指令如下︰
useradd -G {group-name} username
這裡一樣要注意要加入的群組本身必須是已存在的。所以總結來說,當useradd後面接的選項是小寫的g就是加入主群組,大寫的G就是加入副群組。
如果要一次加入數個副群組舉例來說如下︰
# useradd -G admins,www,rd exist_user
這裡表示新增一個叫exist_user 的帳號,並同時把此帳號加入admins、www、rd這幾個群組裡,也就是把要加入的數個群組用逗號串接起來即可。
修改已存在帳號的群組
前兩段都是針對新增帳號的群組所做的說明,那麼如果我們想要修改某個已存在的帳號的主群組和增加副群組呢?這裡用到usermod這個指令,修改主群組指令如下︰
# usermod -g admins my_home
這裡表示我們要把my_home這個帳號的主群組修改為admins。而以下指令︰
# usermod -a -G ftp exist_user
則表示我們把exist_user 這個帳號加入到ftp這個群組。
參考網址
http://mingwang0824.pixnet.net/blog/post/27200755-%5Bsystem%5D%E5%A6%82%E4%BD%95%E5%9C%A8linux%E4%B8%AD%E6%8A%8A%E6%9F%90%E5%80%8Buser%E5%8A%A0%E5%85%A5%E7%BE%A4%E7%B5%84-howto%3A-li

2014年9月5日 星期五

[ubuntu]how to solve Unmet dependencies?

當你在 ubuntu 使用 apt-get install 時碰到 :
E: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).


請執行下列方法:
    sudo apt-get update && sudo apt-get install -f

      若是上述方法無效, 可以再試試看下列方法.

      sudo cp /etc/apt/sources.list ~/ 
      sudo wget "http://pastebin.com/raw.php?i=uzhrtg5M" -O /etc/apt/sources.list 
      sudo apt-get update
      sudo rm /etc/apt/sources.list.d/ubuntu-extras.list
      sudo apt-get update

      apt-get update 失敗
      sudo mv /var/lib/apt /var/lib/apt.old && sudo mv /var/cache/apt /var/cache/apt.old
      sudo rm -rf /var/lib/apt/lists/*

      更強的方式: Link

      2014年1月25日 星期六

      Ubuntu 安裝 JRE

      $ sudo add-apt-repository ppa:webupd8team/java
      $ sudo apt-get update
      $ sudo apt-get install oracle-java7-installer
      若是要移除 $sudo apt-get autoremove oracle-java7-installer
      乾淨移除 $ sudo apt-get --purge remove oracle-java7-installer
      檢查Java版本
      vagrant@precise64:~$ java -version
      java version "1.7.0_51"
      Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

      2013年8月28日 星期三

      [ubuntu] 安裝 nodejs 最新版版


      sudo apt-get install python-software-properties
      sudo add-apt-repository ppa:chris-lea/node.js
      sudo apt-get update
      sudo apt-get install nodejs

      sudo apt-get install npm
      npm install -g karma 針對 angular 測試用

      相關網站 

      2013年4月20日 星期六

      2013年4月4日 星期四

      [ubuntu] 偵測無網路時自動關機

      最近Ubuntu 有時候會開機後抓不到網路,
      所以自然SSH 進去, 只好寫一支shell 去重啟電腦.
      cd /etc/init.d
      將下列存成 sudo vi check_network.sh #!/bin/sh target=192.168.1.1 if ! ping -qnc 1 -w 1 $target > /dev/null ; then sleep 120; if ! ping -qnc 1 -w 1 $target > /dev/null ; then sleep 120; if ! ping -qnc 1 -w 1 $target > /dev/null ; then /sbin/shutdown +5 minutes "Lost network connection" & fi fi fi 變更權限 chmod 755 check_network.sh cd /etc/rc2.d/ sudo ln -s ../init.d/check_network.sh S168check_network Reboot 即可

      2013年1月10日 星期四

      [Ror] 讓ubuntu 在一開機就啟動 rails server

      把下列存成 run_rails_server.sh (記得執行 chmod 755 run_rails_server.sh )
      但是要改 成你自己的Rails project 路徑 /home/rails_path/project
      #! /bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH cd /home/rails_path/project && nohup rails s -p 30000 & 
      執行下列兩行Linux 指令
      sudo cp run_rails_server.sh /etc/init.d/
      sudo ln -s /etc/rc2.d/S168_rails_server.sh /etc/init.d/run_rails_server.sh
      reboot

      2013年1月9日 星期三

      [引用]使用nohup讓程序永遠後台運行


      引用來源:http://www.21andy.com/blog/20071121/677.html

      Unix/Linux下一般比如想讓某個程序在後台運行,很多都是使用 & 在程序結尾來讓程序自動運行。比如我們要運行mysql在後台:
      /usr/local/mysql/bin/mysqld_safe --user=mysql &
      但是加入我們很多程序並不象mysqld一樣做成守護進程,可能我們的程序只是普通程序而已,一般這種程序使用 & 結尾,但是如果終端關閉,那麼程序也會被關閉。但是為了能夠後台運行,那麼我們就可以使用nohup這個命令,比如我們有個test.php需要在後台運 行,並且希望在後台能夠定期運行,那麼就使用nohup:
      nohup /root/test.php &
      提示:
        [~]$ appending output to nohup.out
        嗯,證明運行成功,同時把程序運行的輸出信息放到當前目錄的 nohup.out 文件中去。
        附:nohup命令參考
        nohup 命令
        用途:不掛斷地運行命令。
        語法:nohup Command [ Arg ... ] [ & ]
         描述:nohup 命令運行由 Command 參數和任何相關的 Arg 參數指定的命令,忽略所有掛斷(SIGHUP)信號。在註銷後使用 nohup 命令運行後台中的程序。要運行後台中的 nohup 命令,添加 & ( 表示"and"的符號)到命令的尾部。
         無論是否將 nohup 命令的輸出重定向到終端,輸出都將附加到當前目錄的 nohup.out 文件中。如果當前目錄的 nohup.out 文件不可寫,輸出重定向到 $HOME/nohup.out 文件中。如果沒有文件能創建或打開以用於追加,那麼 Command 參數指定的命令不可調用。如果標準錯誤是一個終端,那麼把指定的命令寫給標準錯誤的所有輸出作為標準輸出重定向到相同的文件描述符。
        退出狀態:該命令返回下列出口值:
        126 可以查找但不能調用 Command 參數指定的命令。
        127 nohup 命令發生錯誤或不能查找由 Command 參數指定的命令。
        否則,nohup 命令的退出狀態是 Command 參數指定命令的退出狀態。
      nohup命令及其輸出文件
        nohup命令:如果你正在運行一個進程,而且你覺得在退出帳戶時該進程還不會結束,那麼可以使用nohup命令。該命令可以在你退出帳戶/關閉終端之後繼續運行相應的進程。nohup就是不掛起的意思( n ohang up)。
      該命令的一般形式為:nohup command &
      使用nohup命令提交作業
      如果使用nohup命令提交作業,那麼在缺省情況下該作業的所有輸出都被重定向到一個名為nohup.out的文件中,除非另外指定了輸出文件:
      nohup command > myout.file 2>&1 &
      在上面的例子中,輸出被重定向到myout.file文件中。
      使用 jobs 查看任務。
      使用 fg %n 關閉。
      另外有兩個常用的ftp工具ncftpget和ncftpput,可以實現後台的ftp上傳和下載,這樣我就可以利用這些命令在後台上傳和下載文件了。

      2012年11月23日 星期五

      To change the default editor nano in Ubuntu Linux


      Ubuntu Linux 在 使用 git 時, 預設是 nano, (還是 vim 比較熟)
      • update-alternatives --config editor
      上述指令會出現如下選項:
         可使用的替換項目
      ===========================
       Selection    Path                優先級  Status
      ------------------------------------------------------------
       * 0            /bin/nano            40        auto mode
        1            /bin/ed             -100       manual mode
        2            /bin/nano            40        manual mode
       3            /usr/bin/vim.basic   30        manual mode
        4            /usr/bin/vim.tiny    10        manual mode


      按下 enter 來指定預設選項[*],或者輸入選擇的號碼: 目前我是選 3 

      2011年10月4日 星期二

      [Linux] Telnet tftpput ssh - expect操作

      首先先安裝EXPECT
      sudo apt-get install expect

      Login telnet : #!/usr/bin/expect spawn telnet 192.168.1.1 expect Login: send root\r expect Password: send password\r interact tftpput : #!/usr/bin/expect spawn tftp 192.168.1.1 expect tftp> send bin\r expect tftp> send "put $argv\r" expect tftp> send quit\r interact 這樣使用 tftpput FILENAME SSH LOGIN : #!/usr/bin/expect -f # Expect script to supply root/admin password for remote ssh server # and execute command. # This script needs three argument to(s) connect to remote server: # password = Password of remote UNIX server, for root user. # ipaddr = IP Addreess of remote UNIX server, no hostname # scriptname = Path to remote script which will execute on remote server # For example: # ./sshlogin.exp password 192.168.1.11 who # ------------------------------------------------------------------------ # Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/> # This script is licensed under GNU GPL version 2.0 or above # ------------------------------------------------------------------------- # This script is part of nixCraft shell script collection (NSSC) # Visit http://bash.cyberciti.biz/ for more information. # ---------------------------------------------------------------------- # set Variables set password [lindex $argv 0] set ipaddr [lindex $argv 1] set scriptname [lindex $argv 2] set arg1 [lindex $argv 3] set timeout -1 # now connect to remote UNIX box (ipaddr) with given script to execute spawn ssh root@$ipaddr $scriptname $arg1 match_max 100000 # Look for passwod prompt expect "*?assword:*" # Send password aka $password send -- "$password\r" # send blank line (\r) to make sure we get back to gui send -- "\r" #expect eof expect "#"

      這樣使用 ./ssh.sh password ipaddr
      解釋: expect "#": 結束expect 返回.
      interact : 最後加這一行, 把控制權交給控制台,這個時候就可以手動操作了.
      proc Login {username server password} { set prompt "(%|>|\#|\\\$) $" spawn /usr/bin/ssh $username@$server expect { -re "Are you sure you want to continue connecting (yes/no)?" { exp_send "yes\r" exp_continue #continue to match statements within this expect {} } -nocase "password: " { exp_send "$password\r" interact } } }
      #!/usr/bin/expect set timeout 1 set cmd {uname -a} spawn ssh root@$argv expect_after eof { exit 0 } ## interact with SSH expect { "(yes/no)?" {send -- "yes\r"; exp_continue} "password:" {send -- "123456\r"} } expect "# " send "$cmd\r" expect "$cmd\r" expect "(.*)\r" send "exit\r
      參考網站:
      不少範例
      http://linux.sheup.com/linux/linux5440.htm
      http://hi.baidu.com/%B7%D7%E7%A1/blog/item/fcb146fb66b95068024f567b.html
      http://www.thegeekstuff.com/2011/01/expect-expressions-loops-conditions/
      http://www.thegeekstuff.com/2010/10/expect-examples/
      Help Expect

      2011年9月7日 星期三

      用shell 來執行 wget

      有時候設定Cron 時, 若是使用php 去跑, 有些環境變數要針對 Cron 來改寫. 所以或許可以使用wget 來取代.

      cronWget.sh 程式碼:
      =============================================
      isLog=$1        
      TargetURL=$2
      LogFile=/var/log/cron.log
      tmpLogFile=/var/log/cron.log.tmp
      export LANG=en_US

      if [ "$isLog" = "1" ]; then
        /usr/bin/wget -q -t 1 -O $tmpLogFile --no-check-certificate $TargetURL

        # append log file
        echo "----------END" >> $LogFile
        cat $tmpLogFile >> $LogFile
        # clean up
        rm -f $tmpLogFile
      =============================================

      Cron 設定方式  /home/cronWget.sh 0 http://192.168.0.1/cron/cron_task.php

      2011年8月1日 星期一

      [引用]理解Linux系統負荷

       一、查看系統負荷
      如果你的電腦很慢,你或許想查看一下,它的工作量是否太大了。
      在Linux系統中,我們一般使用uptime命令查看(w命令和top命令也行)。(另外,它們在蘋果公司的Mac電腦上也適用。)
      你在終端窗口鍵入uptime,系統會返回一行信息。
      這行信息的後半部分,顯示"load average",它的意思是"系統的平均負荷",裡面有三個數字,我們可以從中判斷系統負荷是大還是小。
      為什麼會有三個數字呢?你從手冊中查到,它們的意思分別是1分鐘、5分鐘、15分鐘內系統的平均負荷。
      如果你繼續看手冊,它還會告訴你,當CPU完全空閒的時候,平均負荷為0;當CPU工作量飽和的時候,平均負荷為1。
      那麼很顯然,"load average"的值越低,比如等於0.2或0.3,就說明電腦的工作量越小,系統負荷比較輕。
      但是,什麼時候能看出系統負荷比較重呢?等於1的時候,還是等於0.5或等於1.5的時候?如果1分鐘、5分鐘、15分鐘三個值不一樣,怎麼辦?

      2011年4月22日 星期五

      [ubuntu] 自動刪除幾天前備份檔案shell 程式

      因為有個資料夾內, 有備份sql 的資料, 但是又擔心, 若是一直砍, 哪天資料備份故障, 這樣檔案還是會被砍光.
      因此加了個判斷.
      該資料夾內檔案若是高於5筆 , 才進行刪除動作.
      程式如下:
      ------------------------------------------------------------------------
      #!/bin/sh
      file_num=$(find /home/xxx/secret/*.bak |wc -l);
      if [ $file_num -gt 5 ]; then
      find /home/xxx/secret/*.bak -type f -mtime +6 |xargs --no-run-if-empty rm -rf
      fi
      ------------------------------------------------------------------------
      存成 rm_sqlback.sh  (權限要改成可以執行的)
      加入到 crontab 中

      0 1 * * * /bin/sh /root/rm_sqlback.sh


      ------------------------------------------------------------------------

      補充 xargs :

      find -iname "*.bak" | xargs -i cp {} ~/bakdir


      使用 -i 和 {}  就可以把前面所得到的輸出列表,不是一整串,而是一個一個地傳給後面的指令
      上述的指令的效果就像是這樣…

      cp ./VERSION.bak ~/bakdir
      cp ./inc/main.h.bak ~/bakdir
      cp  ./src/fork.c.bak ~/bakdir
      cp  ./src/common_lib/dl_string.c.bak ~/bakdir
      cp  ./src/common_lib/dl_math.c.bak ~/bakdir

      參考:
      鳥哥的Linux 私房菜-- 學習Shell Scripts
      ddy 狡兔三窟之一: xargs 應用介紹(例)

      2011年3月28日 星期一

      [Ubuntu] 設定 Wake On Lan 網路喚醒


      透過NAS 來 wake on lan  另一台ubuntu 的server .
      這台ubuntu 的server 主要是做 Raid1 , rsync NAS 內的部分資料. 
      因為只是一般電腦組成的ubuntu 所以經不起24小時開機(因為power 已經在之前使用3-4年後掛點過), 所以透過NAS 執行crontab 去執行php 程式去喚醒他. 

      // 安裝 ethtool 工具

      $ sudo atp-get install ethtool 

      $ sudo ethtool eth0
      Settings for eth0:
          Supported ports: [ TP ]
          Supported link modes:   10baseT/Half 10baseT/Full
                                  100baseT/Half 100baseT/Full
                                  1000baseT/Full
          Supports auto-negotiation: Yes
          Advertised link modes:  10baseT/Half 10baseT/Full
                                  100baseT/Half 100baseT/Full
                                  1000baseT/Full
          Advertised pause frame use: No
          Advertised auto-negotiation: Yes
          Speed: 1000Mb/s
          Duplex: Full
          Port: Twisted Pair
          PHYAD: 0
          Transceiver: internal
          Auto-negotiation: on
          MDI-X: Unknown
          Supports Wake-on: umbg
          Wake-on: d
          Current message level: 0x00000007 (7)
          Link detected: yes


      // Wake-on: d  d: disable , g: enable

      $ sudo ethtool -s eth0 wol g // 設定成g


      獲取遠端機器網卡的Mac address:
      $ ifconfig
      eth0      Link encap:Ethernet  HWaddr 08:00:27:26:c0:17  
                inet addr:192.168.3.15  Bcast:192.168.3.255  Mask:255.255.255.0
                inet6 addr: fe80::a00:27ff:fe26:c017/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                RX packets:3497 errors:0 dropped:0 overruns:0 frame:0
                TX packets:439 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000
                RX bytes:998035 (998.0 KB)  TX bytes:50331 (50.3 KB)
      記下網卡MAC地址。
      在本地主機安裝網絡喚醒軟件:
      $sudo apt-get install wakeonlan
      通過以下命令,實現遠程開機: 
      $ wakeonlan 08:00:27:26:c0:17
      修改這檔案可以讓 Wake on lan 自動啟用
      /etc/network/interfaces:

      iface eth0 inet dhcp
              post-up /sbin/ethtool -s $IFACE wol g
              post-down /sbin/ethtool -s $IFACE wol g
      

      在本地主機上要想遠程啟動遠程服務器,必須輸入:wakeonlan 08:00:27:26:c0:17 命令,那麽你可以通過以下方法來減化操作:(以下操作都是在本地主機上進行)
      在桌面環境下新建一個文本文件,命名爲 wakeupcomputer
      在文本裏輸入以下內容:
      wakeonlan  08:00:27:26:c0:17
      保存,退出。
      進行文件可執行化操作:
      $chmod 755 wakeupcomputer
      然後將其移到到 /usr/local/bin文件夾
      $sudo mv wakeupcomputer /usr/local/bin
      (如果你高興,也可以通過以下命令將wakeupcomputer文件改爲root名下的:
      $sudo chown root:root /usr/local/bin/wakeupcomputer
      )
      現在,你可以在遠程主機未啟動的情況下,在本地主機命令行下輸入以下命令
      $wakeupcomputer
      來實現自動遠程啟動遠程主機了。


      參考網址:http://wiki.debian.org/WakeOnLan


      透過PHP來達到 Wake on Lan

      <?php
      function Encryption($decrypted_data) {
      if (!extension_loaded('mcrypt')) {
      $encrypted_data = $decrypted_data;
      }
      else {
      //opens the cipher module
      $TD = mcrypt_module_open('tripledes', '', 'ecb', '');
      //create the IV and determine the keysize length, used MCRYPT_RAND on Windows instead
      $IV = mcrypt_create_iv (mcrypt_enc_get_iv_size($TD), MCRYPT_RAND);
      //initialize encryption-buffers
      //require("Includes/config.php");
      $key = "Masterkey";
      $key = substr($key, 0, mcrypt_enc_get_key_size($TD));
      $s=mcrypt_generic_init($TD, $key, $IV);
      if( ($s < 0) || ($s === false)) {
      die ("Foutmelding: niet in staat om de encryptiebuffers te initializeren!");
      }
      mcrypt_generic_init($TD, $key, $IV);
      //encrypt data
      $encrypted_data = mcrypt_generic($TD, $decrypted_data);
      //terminate handler and close module
      mcrypt_generic_deinit($TD);
      mcrypt_module_close($TD);
      unset($key);
      }
      return $encrypted_data;
      }
      // Custom error handler
      function customError($error_level,$error_message,$error_file,$error_line,$error_context)
      {
      global $handler_error;
      if (substr_count($error_message, "fsockopen() [") && substr_count($error_message, "]: unable to connect to udp://") && substr_count($error_message, " (Permission denied)"))
      {
      // Since this error is already caught, it can be surpressed.
      }
      else
      {
      if (substr_count($error_message, "It is not safe to rely on the system's timezone settings. "))
      {
      $_SESSION['local_timezone_set'] = "Since no timezone was specified, the timezone of the webserver will be used.<br>\n";
      }
      else
      {
      $_SESSION['handler_error'] = $_SESSION['handler_error']."<br>error_level: ".$error_level."<br>error_message: <b>".$error_message."</b><br>error_file: ".$error_file."<br>error_line: ".$error_line."<br>error_context: ".$error_context."<br>\n";
      }
      }
      return;
      }

      function WakeOnLan($time_string, $mac_address, $secureon, $addr, $cidr, $port, $store)
      {
      // Start session (for use with Ajax-script)
      session_start();
      //Set error handler
      set_error_handler("customError");
      // If $time_string is empty
      if($time_string == "")
      {
      $time_string = "+0 seconds";
      }
      //Check whether $time_string is valid (pattern)
      if (!preg_match("/^[(\w)(\+)(\-)(:)( )(\/)]+$/",$time_string))
      {
      $error = "Input error: Time/ Delay does not consist of only digits and/ or characters<br>\n";
      return $error; // false
      }
      // Determine Timezone from $time_string
      $a = date_create($time_string); // create date_object from $time_string
      $b = date_timezone_get($a); // create datetimezone_object from date_object
      if(!$b)
      {
      $error = "Input error: Timezone is unknown (unlisted in the timezone database of PHP on this webserver).<br>\n";
      return $error; // false
      }
      $c = timezone_name_get($b); // get timezone abbreviaton from datetimezone_object
      $d = timezone_name_from_abbr($c); // get timezone identifier from timezone abbreviation
      if ($d)
      {
      date_default_timezone_set($d);
      }
      else
      {
      date_default_timezone_set($c);
      }
      // Calculate $delay
      $time_script_start = time();
      $timestamp_new_send = strtotime($time_string);
      $delay = ($timestamp_new_send - $time_script_start);
      //Check whether $time_string is valid (value)
      if ($delay < 0)
      {
      $error = "Input error: Wake-up time is not set in the future.<br>\n";
      return $error; // false
      }
      // Force a minimum delay to prevent abuse (e.g., DOS-attacks)
      if ($delay < 3)
      {
      $delay = 3;
      }
      // Prepare magic packet: part 1/3 (defined constant)
      $buf="";
      for($a=0; $a<6; $a++) $buf .= chr(255); // the defined constant as represented in hexadecimal: FF FF FF FF FF FF (i.e., 6 bytes of hexadecimal FF)
      //Check whether $mac_address is valid
      $mac_address=strtoupper($mac_address);
      $mac_address=str_replace(":", "-", $mac_address);
      if ((!preg_match("/([A-F0-9]{2}[-]){5}([0-9A-F]){2}/",$mac_address)) || (strlen($mac_address) != 17))
      {
      $error = "Input error: Pattern of MAC-address is not \"xx-xx-xx-xx-xx-xx\" (x = digit or letter).<br>\n";
      return $error; // false
      }
      else
      {
      // Prepare magic packet: part 2/3 (16 times MAC-address)
      $addr_byte = explode('-', $mac_address); // Split MAC-address into an array of (six) bytes
      $hw_addr="";
      for ($a=0; $a<6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a])); // Convert MAC-address from bytes to hexadecimal to decimal
      $hw_addr_string="";
      for ($a=0; $a<16; $a++) $hw_addr_string .= $hw_addr;
      $buf .= $hw_addr_string;
      }
      if ($secureon != "")
      {
      // Check whether $secureon is valid
      $secureon=strtoupper($secureon);
      $secureon=str_replace(":", "-", $secureon);
      if ((!preg_match("/([A-F0-9]{2}[-]){5}([0-9A-F]){2}/",$secureon)) || (strlen($secureon) != 17))
      {
      $error = "Input error: Pattern of SecureOn-password is not \"xx-xx-xx-xx-xx-xx\" (x = digit or CAPITAL letter).<br>\n";
      return $error; // false
      }
      else
      {
      // Prepare magic packet: part 3/3 (Secureon password)
      $addr_byte = explode('-', $secureon); // Split MAC-address into an array of (six) bytes
      $hw_addr="";
      for ($a=0; $a<6; $a++) $hw_addr .= chr(hexdec($addr_byte[$a])); // Convert MAC address from hexadecimal to decimal
      $buf .= $hw_addr;
      }
      }
      // To support web proxy users
      if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
      {
      $current_client_IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
      }
      elseif (isset($_SERVER['HTTP_CLIENT_IP']))
      {
      $current_client_IP = $_SERVER['HTTP_CLIENT_IP'];
      }
      else
      {
      $current_client_IP = $_SERVER['REMOTE_ADDR'];
      }
      // Fill $addr with client's IP address, if $addr is empty
      if ($addr == "")
      {
      $addr = $current_client_IP;
      }
      // Resolve broadcast address
      if (filter_var ($addr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) // same as (but easier than): preg_match("/\b(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\b/",$addr)
      {
      // $addr has an IP-adres format
      }
      else
      {
      // Whitespaces confuse name lookups
      $addr=trim($addr);
      // If you pass to gethostbyname() an:
      // unresolvable domainname, gethostbyname() returns the domainname (rather than 'false')
      // IP address, gethostbyname() returns that IP address.
      if (gethostbyname($addr) == $addr)
      {
      // $addr is NOT a resolvable domainname
      $error = "Input error: host name of broadcast address is unresolvable.<br>\n";
      return $error; // false
      }
      else
      {
      // $addr IS a resolvable domainname
      $addr = gethostbyname($addr);
      }
      }
      // Store input value for cookie
      $resolved_addr = $addr;
      // If $cidr is set, replace $addr for its broadcast address
      if ($cidr != "")
      {
      // Check whether $cidr is valid
      if ((!ctype_digit($cidr)) || ($cidr < 0) || ($cidr > 32))
      {
      $error = "Input error: CIDR subnet mask is not a number within the range of 0 till 32.<br>\n";
      return $error; // false
      }
      // Convert $cidr from one decimal to one inverted binary array
      $inverted_binary_cidr="";
      for ($a=0; $a<$cidr; $a++) $inverted_binary_cidr .= "0"; // Build $inverted_binary_cidr by $cidr * zeros (this is the mask)
      $inverted_binary_cidr = $inverted_binary_cidr.substr("11111111111111111111111111111111",0,32-strlen($inverted_binary_cidr)); // Invert the mask (by postfixing ones to $inverted_binary_cidr untill 32 bits are filled/ complete)
      $inverted_binary_cidr_array = str_split($inverted_binary_cidr); // Convert $inverted_binary_cidr to an array of bits
      // Convert IP address from four decimals to one binary array
      $addr_byte = explode('.', $addr); // Split IP address into an array of (four) decimals
      $binary_addr="";
      for ($a=0; $a<4; $a++) {
      $pre = substr("00000000",0,8-strlen(decbin($addr_byte[$a]))); // Prefix zeros
      $post = decbin($addr_byte[$a]); // Postfix binary decimal
      $binary_addr .= $pre.$post;
      }
      $binary_addr_array = str_split($binary_addr); // Convert $binary_addr to an array of bits
      // Perform a bitwise OR operation on arrays ($binary_addr_array & $inverted_binary_cidr_array)
      $binary_broadcast_addr_array="";
      for ($a=0; $a<32; $a++) $binary_broadcast_addr_array[$a] = ($binary_addr_array[$a] | $inverted_binary_cidr_array[$a]); // binary array of 32 bit variables ('|' = logical operator 'or')
      $binary_broadcast_addr = chunk_split(implode("", $binary_broadcast_addr_array),8,"."); // build binary address of four bundles of 8 bits (= 1 byte)
      $binary_broadcast_addr = substr($binary_broadcast_addr,0,strlen($binary_broadcast_addr)-1); // chop off last dot ('.')
      $binary_broadcast_addr_array = explode(".", $binary_broadcast_addr); // binary array of 4 byte variables
      $broadcast_addr_array="";
      for ($a=0; $a<4; $a++) $broadcast_addr_array[$a] = bindec($binary_broadcast_addr_array[$a]); // decimal array of 4 byte variables
      $addr = implode(".", $broadcast_addr_array); // broadcast address
      }
      // Check whether $port is valid
      if ((!ctype_digit($port)) || ($port < 0) || ($port > 65536))
      {
      $error = "Input error: Port is not a number within the range of 0 till 65536.<br>\n";
      return $error; // false
      }
      // Check whether UDP is supported
      if (!array_search('udp', stream_get_transports()))
      {
      $error = "No magic packet can been sent, since UDP is unsupported (not a registered socket transport).<br>\n";
      return $error; // false
      }
      // COOKIE
      // Build contents of cookie
      $delimiter = "<->";
      $contents = "prefix".$delimiter.$_SERVER['HTTP_USER_AGENT'].$delimiter.$time_string.$delimiter.$mac_address.$delimiter.$secureon.$delimiter.$resolved_addr.$delimiter.$cidr.$delimiter.$port.$delimiter.$store.$delimiter."postfix";
      // Encrypt contents of cookie
      //require("Includes/Encryption.php");
      $encrypted = Encryption($contents);
      // Write cookie (31557600 seconds = 365,25 days which includes 1 leap day per 4 years)
      if ($store == "Yes")
      {
      setcookie("WOL", base64_encode($encrypted), time()+31557600, "/");
      }
      else
      {
      setcookie("WOL", "", time()-3600, "/");
      }
      // Display this value AFTER the header was sent and after the cookie was set
      echo ($_SESSION['local_timezone_set']);
      unset($_SESSION['local_timezone_set']);
      // Simulate crontask behaviour
      ignore_user_abort(true); // so the user can not stop the script (running in background).
      set_time_limit(0); // parsing this script may take forever (no time limit is imposed)
      // WHY_1?
      ob_start(); // ???
      ob_implicit_flush();
      // WHY_1?
      //query_string
      $query_string = "";
      foreach ($_POST as $key => $value) {
      $post_variable[] = "$key=$value";
      }
      $query_string = "?".join("&", $post_variable);
      // HTML-table
      $pre_table = "Bookmark or click <a href=\"".$query_string."\">this</a> URL to repeat this WOL-request.<br>\n";
      $pre_table = $pre_table."<table border=\"1\"><tr><th></th><th>dd-mm-yyyy</th><th>hh:mm:ss</th><th>timezone</th></tr>\n";
      $pre_table = $pre_table."<tr><td>Sleeping at</td><td>".date("d-m-y",$time_script_start)."</td><td>".date("H:i:s",$time_script_start)."</td><td>".date("e",$time_script_start)."</td></tr>\n";
      $pre_table = $pre_table."<tr><td>Will be resuming at</td><td>".date("d-m-y",$time_script_start+$delay)."</td><td>".date("H:i:s",$time_script_start+$delay)."</td><td>".date("e",$time_script_start+$delay)."</td></tr>\n";
      echo ($pre_table);
      echo str_repeat(" ",256); // Some versions of MS IE will only start to display the page, after they have received 256 bytes.
      // WHY_2?
      ob_flush();
      flush();
      ob_end_clean(); // ???
      // WHY_2?
      // SLEEP
      sleep($delay);
      // Wake up
      $post_table = "<tr><td>Resumed at</td><td>".date("d-m-y",time())."</td><td>".date("H:i:s",time())."</td><td>".date("e",time())."</td></tr></table>\n";
      echo ($post_table);
      if (function_exists('fsockopen'))
      {
      // Try fsockopen function - To do: handle error 'Permission denied'
      $socket=fsockopen("udp://" . $addr, $port, $errno, $errstr);
      if($socket)
      {
      $socket_data = fwrite($socket, $buf);
      if($socket_data)
      {
      $function = "fwrite";
      $sent_fsockopen = "A magic packet of ".$socket_data." bytes has been sent via UDP to IP address: ".$addr.":".$port.", using the '".$function."()' function.<br>";
      $content = bin2hex($buf);
      $sent_fsockopen = $sent_fsockopen."Contents of magic packet:<br><textarea rows=\"1\" name=\"content\" cols=\"".strlen($content)."\">".$content."</textarea><br>\n";
      fclose($socket);
      unset($socket);
      return $sent_fsockopen; // true
      }
      else
      {
      echo "Using 'fwrite()' failed, due to error: '".$errstr."' (".$errno.")<br>\n";
      fclose($socket);
      unset($socket);
      }
      }
      else
      {
      echo "Using 'fsockopen()' failed, due to denied permission.<br>\n";
      unset($socket);
      }
      }
      // Try socket_create function
      if (function_exists('socket_create'))
      {
      $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // create socket based on IPv4, datagram and UDP
      if($socket)
      {
      $level = SOL_SOCKET; // to enable manipulation of options at the socket level (you may have to change this to 1)
      $optname = SO_BROADCAST; // to enable permission to transmit broadcast datagrams on the socket (you may have to change this to 6)
      $optval = true;
      $opt_returnvalue = socket_set_option($socket, $level, $optname, $optval);
      if($opt_returnvalue < 0)
      {
      $error = "Using 'socket_set_option()' failed, due to error: '".socket_strerror($opt_returnvalue)."'<br>\n";
      return $error; // false
      }
      $flags = 0;
      // To do: handle error 'Operation not permitted'
      $socket_data = socket_sendto($socket, $buf, strlen($buf), $flags, $addr, $port);
      if($socket_data)
      {
      $function = "socket_sendto";
      $socket_create = "A magic packet of ".$socket_data." bytes has been sent via UDP to IP address: ".$addr.":".$port.", using the '".$function."()' function.<br>";
      $content = bin2hex($buf);
      $socket_create = $socket_create."Contents of magic packet:<br><textarea rows=\"1\" name=\"content\" cols=\"".strlen($content)."\">".$content."</textarea><br>\n";
      socket_close($socket);
      unset($socket);
      return $socket_create; // true
      }
      else
      {
      $error = "Using 'socket_sendto()' failed, due to error: '".socket_strerror(socket_last_error($socket))."' (".socket_last_error($socket).")<br>\n";
      socket_close($socket);
      unset($socket);
      return $error; // false
      }
      }
      else
      {
      $error = "Using 'socket_create()' failed, due to error: '".socket_strerror(socket_last_error($socket))."' (".socket_last_error($socket).")<br>\n";
      return $error; // false
      }
      }
      else
      {
      $error = "No magic packet has been sent, since no functions are available to transmit it.<br>\n";
      return $error; // false
      }
      }

      // Note: This script validates all user input (as a protection against code injection).
      $time_string = '+3 seconds';
      $mac_address = '00:1a:4d:8b:00:d4';
      $secureon = $_REQUEST['secureon'];
      $addr = '192.168.100.2';
      $cidr = '24';
      $port = '7';
      $store = 'No';

      $Return_WakeOnLan = WakeOnLan($time_string, $mac_address, $secureon, $addr, $cidr, $port, $store); // executes this function
      ?>

      2011年3月4日 星期五

      Linux diff and colordiff

      來源

      * diff -u file1 file2 | colordiff
      * diff -u file1 file2 | colordiff | less -R
      * 直接寫 alias diff=colordiff 進 .bashrc, 就可以直接 diff -u file1 file2 | less -R 囉~
      * 加上 -u 的參數, 不同的地方會以 +/- 來區分, 會比較好看.
      安裝: apt-get install colordiff 即可

      2011年2月24日 星期四

      SSH 遠端登入免密碼 by RSA

      $ ssh-keygen -t rsa 再client 端產生密鑰 .  持續enter 一直按就可以產生.
        另外 若是打這樣 連後面 enter 都不用按 ssh-keygen -t rsa -P ''
      # id_rsa.pub = public key.
      # id_rsa = private key.

      $ cat .ssh/id_rsa.pub | ssh user@Server "cat - >> .ssh/authorized_keys"
      # user= 登入user 帳號
      # Server = Domain name or IP address.


      參考來源: http://jonny.ubuntu-tw.net/2010/06/ssh-by-rsa.html

      2011年2月23日 星期三

      [引用]Ubuntu Linux 挑選最佳的 Mirror Site

      來源
      最近 tw.archive.ubuntu.com 經常連不上, 所以先暫時把這個換掉. (於 "更新管理員" 看到 "上次更新套件資訊是 7天前"...)

      要換掉 tw.archive.ubuntu.com, 其他的 Mirror site list 在哪裡? 另外, 有那麼多的 Mirror site, 要如何挑選呢?

      Ubuntu Linux 挑選最佳的 Mirror Site (Repository) 的步驟
      cp /etc/apt/sources.list /etc/apt/sources.list.20110222 # 備份
      Synaptic -> 設定 -> 套件庫 # 或直接 sudo /usr/bin/software-properties-gtk
      軟體來源 -> Tab 選 "Ubuntu 軟體"
      找到 下載自 "用於 台灣 的伺服器" 這欄位, 點選下拉, 選 "其它"
      點選 "選擇最佳的伺服器" # 會跑所有伺服器速度測試
      跑完後點選 "選擇伺服器" 即可.
      我的是最佳選擇是 http://ftp.tku.edu.tw/ubuntu # 依照 ISP 不同, 結果應該不會一樣.
      上述步驟, 此篇有圖文說明: How To select fastest mirror in Ubuntu | Ubuntu Geek
      Ubuntu Mirror Site List
      除了自動挑選外, 也可以自己由 Mirror site list 挑選, 此 List 也有紀錄此 鏡像站(Mirror site) 的 更新頻率 如何.

      所有 Ubuntu Mirror Site List 可見下述: # 取自: Repositories Using the Command Line

      Mirrors of Ubuntu : Ubuntu - 各個地區得 Mirror site list, 更新頻率 .. 等資訊
      Mirrors - Ubuntu Wiki
      Ubuntu /etc/apt/sources.list 產生工具
      Ubuntu Sources List Generator
      Ubuntu Server 的 "Best Server" 挑選
      在 Desktop 有 GUI 可以用, 但是 Ubuntu Server 沒辦法使用. 於是要找出 "Select Best Server" 底層是如何運作, 可以見下述文章:

      Tweaking Ubuntu's 'Select Best Server' so it ACTUALLY WORKS # Select Best Server 真實工作狀態
      "Select Best Server" 主要挑選的 Script 可見: /usr/share/pyshared/softwareproperties/MirrorTest.py
      於 Ubuntu Server 的 Mirror site 選擇方式:

      目前沒找到可以直接於 CLI 執行的程式, 可以修改這隻程式 ( /usr/share/pyshared/softwareproperties/MirrorTest.py ) 來挑選
      hychen 有寫好的 CLI 版挑選 Mirror site 程式: getfastmirror
      或於 Desktop 跑完後, 手動將 sources.list scp 過去 Server 上. :)
      相關說明
      Repositories/Ubuntu
      SourcesList
      相關網頁
      換 Ubuntu 的 mirror site…
      Apt-spy - 於 Debian 可以用 apt-spy 來挑選最佳的 Mirror site.

      2011年1月12日 星期三

      ubuntu install spark command

      就下列三行指令
      先下載 Spark2.5.8
      $ tar -xzf spark_2_5_8.tar.gz
      $ cd Spark
      $ ./starter

      記起來...