改進 ownCloud 的效能

ownCloud 背景也有一些事情要做,例如隔幾天要把垃圾桶給清乾淨,一些例行事情如果沒有週期性的執行,那麼 ownCloud 就只能等每個指令來的時候偷偷檢查一下,這倒是增加了ownCloud 和系統的負擔,所以我們要把這些例行性事情改用 crontab 來做,而非預設的 AJAX 來做!

首先在命令列下一道指令。

# crontab -u www-data -e

然後就可以編輯 crontab ,在這個檔案後面加上

*/15 * * * * php -f /var/www/owncloud/cron.php

讓 ownCloud 的cron.php 每隔十五分鐘執行一次,也可以是三十分鐘執行一下。存檔後再到 ownCloud 管理網頁下查看一下是否已經更改為 cron 了呢?

1

如何防範 SMTP 暴力式攻擊

暴力式攻擊是泛指使用常用字眼攻擊某些協議的通訊埠,進而嘗試取得密碼。這種攻擊十分討厭,既無技術可而,但安全上卻是個問題,而且系統還要耗掉一些效能來應付,所以這一篇我們講講如何使用 iptables 來防範 SMTP 的暴力式攻擊。

一個正常的 SMTP 的通訊內容大約是這樣的

# telnet mail.example.org 25
Trying 1.2.3.4...
Connected to mail.example.org.
Escape character is '^]'.
220 mail.example.org ESMTP
EHLO brute.attack.com
250-mail.example.org
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH LOGIN
334 VXNlcm5hbWU6
dXNlcm5hbWUuY29t
334 UGFzc3dvcmQ6
bXlwYXNzd29yZA==
535 5.7.8 Error: authentication failed:

所以密碼錯誤驗證失敗最後面一定會有個錯誤碼 535 5.7.8,這次我們利用這個字串來告訴 iptables 如果某 IP 在 180 秒內連續三次出現這個字眼就把封包給攔截,這樣就達到防堵 SMTP 暴力式攻擊了。

# iptables -I OUTPUT -p tcp --sport 25 -m string --to 90 --string "535 5.7.8 Error: authentication failed:" --algo bm -m recent --rdest --name SMTP_AUTH_ERROR --set
# iptables -I OUTPUT -m recent --name SMTP_AUTH_ERROR --rdest --rcheck --seconds 180 --hitcount 3 -j DROP

這樣 iptables 就會根據這個字串來封鎖一些惡意攻擊 SMTP 的 IP 地址。

如何讓 Apache 不要紀錄機器人要網頁的紀錄

我有一個習慣會去定期地看系統 log 檔案,以防止有什麼攻擊或是重大事件發生。但是 Apache 的 access log 實在太多了,我想我的網站應該還沒有那麼受歡迎吧,一天來個一百個人就算多了,我分析了一下大部分都是機器人來搜尋網頁的紀錄,所以我決定不要紀錄這些無關痛癢的存取動作,好讓我專心的看 access log。

之前我有一篇教學是在講 Apache 的怎麼不要紀錄的,請參考這裡。我們這篇再深入一點,把這些機器人或是RSS Feed給剔除掉。所以我們必須增加一些關鍵字,而關鍵字的內容我會繼續增加的。

SetEnvIfNoCase User-Agent "Googlebot" dontlog
SetEnvIfNoCase User-Agent "AhrefsBot" dontlog
SetEnvIfNoCase User-Agent "Baiduspider" dontlog
SetEnvIfNoCase User-Agent "MJ12bot" dontlog
SetEnvIfNoCase User-Agent "Sogou web spider" dontlog
SetEnvIfNoCase User-Agent "AppEngine-Google" dontlog
SetEnvIfNoCase User-Agent "bingbot" dontlog
SetEnvIfNoCase User-Agent "Digg Feed Fetcher" dontlog
SetEnvIfNoCase User-Agent "FlipboardRSS" dontlog
SetEnvIfNoCase User-Agent "Xianguo.com" dontlog
SetEnvIfNoCase User-Agent "WordPress/PuSHPress" dontlog
SetEnvIfNoCase User-Agent "Superfeedr" dontlog
SetEnvIfNoCase User-Agent "Feedly" dontlog
SetEnvIfNoCase User-Agent "FlipboardProxy" dontlog
SetEnvIfNoCase User-Agent "meanpathbot" dontlog
SetEnvIfNoCase User-Agent "360Spider" dontlog
SetEnvIfNoCase User-Agent "Yahoo! Slurp" dontlog
SetEnvIfNoCase User-Agent "Sleipnir" dontlog
SetEnvIfNoCase User-Agent "NerdyBot" dontlog

以上都是一些常見機器人,例如:Google或是百度,以及RSS Feed的關鍵字,把它增加到 /etc/apache2/sites-enabled/000-default.conf 的虛擬機器 80 和 443裡面,增加完必須重啟 apache  服務方能生效。

# service apache2 restart

如何將 WordPress 圖片加上快取圖片

一般  WordPress 的圖片不太會更動,所以當使用者瀏覽網頁時可以把圖片快取下來,下次觀看時就可以不必重新下載圖片,直接使用電腦上快取的圖片,以節省頻寬以及效能。我們就來談談如何實現這個功能。

首先,在 /etc/apache2/mods-enabled/ 目錄下必須要有expires.load 這個模組,在我的 CubieTruck 底下是沒有的,所以必須把 /etc/apache2/mods-available的expireds.load 連結到 /etc/apache2/mods-enabled 裡面。

# ln -s /etc/apache2/mods-available/expires.load /etc/apache2/mods-enabled/

這樣就可以把模組給鏈結進來,不過要重啟服務一下,讓 apache2 把 expires.load 正式加進來。

# service apache2 restart

然後編輯 WordPress 根目錄底下的 .htaccess 檔案

# nano /var/www/wordpress/.htaccess

在檔案底下增加

#Expire Header
<FilesMatch "\.(ico|jpg|jpeg|png|gif|js|css|swf)$">
ExpiresDefault "access plus 2 hours"
</FilesMatch>

把所有圖檔格式的快取時間設定為兩個小時,也可以對不同檔案分別設定。

# Expire images header
ExpiresActive On
ExpiresDefault A0
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/ico A2592000
ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000

2592000 是指快取一個月 24 * 60 * 60 *30 = 2592000。 .htaccess 存檔後就可以直接套用了,不需要重啟 apache2 服務。

如何確認 WordPress 是採用 InnoDB 還是MyISAM資料庫方式

WordPress是採用 mysql 當做資料庫後端程式,而 mysql 有分為 InnodDB和MyISAM兩種資料庫方式,這兩種各有優劣。我們這一篇不討論到底誰的效能比較好,因為我覺得在討論之前,我們總得先知道我們 WordPress 目前是採用哪種方式,然後再來討論如何優化,否則一切徒勞無功。

首先我們先進入 mysql 後台。

# mysql -u root -p

輸入 root 密碼後就可以進入mysql 的後台,然後我們輸入。

mysql> select TABLE_NAME, ENGINE from information_schema.TABLES WHERE TABLE_SCHEMA='wordpress';

此時就會輸出,
1

 

或是

2

這時候,mysql ENGINE就會告訴你 WordPress的所有表格到底是採用InnoDB 或是 MyISAM哪個方式了,我的 CubieTruck是InnoDB的,得找些資料來優化優化了。

如何把 WordPress 的圖片再壓縮一次

之前在寫 Android 程式時,就領教過把圖片無失真再壓縮一次可以節省很多空間,真正原理我不太清楚,但無非是把一些注釋,不重要的資訊給刪除。反正 WordPress 的圖片是用來參考用的,所以有沒有這些資訊無所謂,所以我決定再把這些 jpg 檔案在進行一次壓縮。

原本我考慮是用 trimage 這個套件的,因為它可以套用不只 jpg 還可以對 png 做壓縮,但是當我安裝時才發現這個套件安裝要 100 MB以上,所以我打了退堂鼓,退而求其次改安裝 jpegoptim 這個套件,雖然安裝所需空間小很多,但是只能對 jpg 有用。

首先,我們透過 apt-get 來安裝 jpegoptim 套件。

# apt-get install jpegoptim

這個套件大約只需要600-700KB而已,然後切換到 wordpress 上傳影像區,結合 find 指令,把所有 jpg 檔案找出來,然後透過 jpegoptim 來二次壓縮。

# cd /var/www/wordpress/wp-content/upload
# find . -type f -name \*.jpg -exec jpegoptim {} \;
# find . -type f -name \*.jpg -exec chmod 644 {} \;
# chown -R www-data:www-data /var/www/wordpress/wp-content/upload

最後兩行是因為重新建立 jpg 時的權限可能被更改成其他人,進行再次修改回來成正確權限。

如何把 WordPress 的文字檔案以壓縮方式傳送

WordPress是一個著名架部落客的套件,基於 Apache/PHP5/MySQL 服務底下,效率算起來還不錯。但是我們可以透過修改 .htaccess 檔案把一些文字的檔案來進行壓縮傳送,減少頻寬。等到客戶接收端收到之後再進行解壓縮即可。

這一次我們要修改 /var/www/wordpress 目錄底下的 .htaccess,藉此把這一整個目錄的文字類檔案來壓縮

# nano /var/www/wordpress/.htaccess

在這個檔案後面加上這三行

<FilesMatch ".(js|css|html|htm|php|xml)$">
SetOutputFilter DEFLATE
</FilesMatch>

存檔即可生效,不需要重啟服務。但是效果是有限的,因為一般文章的長度不會太長,壓縮起來效率不好,反而浪費時間在壓縮和解壓縮裡面,所以自己要權衡一下。

CubieTruck上MySQL的效能調校

雖然CubieTruck的CPU比起Intel系列的CPU實在不怎麼樣,但是優點是記憶體有2GB大,可以用來揮霍一下。因為這台 CubieTruck 普通時也沒有跑其他什麼服務,所以希望能把多餘的記憶體用在 mysql 上,希望 WordPress 能載入快一點,雖說我已經把 mysql databases 都移到硬碟上了,畢竟記憶體還是比硬碟快。

這一次我們會動到 /etc/mysql/my.cnf 檔案裡面兩個參數,innodb_buffer_pool_size innodb_log_buffer_size,但在修改之前我們想先觀察一下預設值到底是多少。先在終端機上登入 mysql 後台

# mysql -u root -p

然後輸入 root 的密碼,在 mysql 後台輸入

mysql >SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
mysql >SHOW VARIABLES LIKE 'innodb_log_buffer_size';

這樣 mysql 就可以秀出預設值分別是128MB和8MB,我決定把他們加大一些,所以必須修改/etc/mysql/my.cnf 檔案,編輯這個檔案然後找到 [mysqld] 這個段落,之後寫入

[mysqld]
...
innodb_buffer_pool_size = 256M
innodb_log_buffer_size = 32M

存檔之後必須重啟 mysql 服務方能生效。

# service mysql restart

再進入 mysql 後台觀察是否數值已經被改變了呢?如果是的話就觀察一下效能是否有增加囉!

Linux Bash Shell 資安大漏洞以及解決辦法

繼上次 SSL Heart Bleed 心臟淌血事件,這次換我們常用的Bash Shell 也中招了,駭客可以利用特殊代碼執行不知名的變數侵入系統,包含 Mac OS, Linux等等。危害的程度不比上次心臟淌血來的小,因為系統內很多的 script 就是用 bash 寫的,首先我們先來看看如何驗證是否自己的系統的 bash shell 中招了(不能用版號區分),在終端機下輸入

# env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

如果終端機出現

vulnerable
this is a test

恭喜你,你的系統  Bash Shell 中招了,駭客可能會利用此漏洞取得非法資料,此次的漏洞代碼稱之為 CVE-2014-6271,各位可以參訪  美國國土安全部旗下的電腦警備小組網站 去下載自己作業系統的更新檔案,趕快更新以免駭客有機可乘。

us-cert

因為筆者的作業系統是 Ubuntu 14.04,所以 Ubuntu 修補相關連結

Ubuntu Security Notice USN-2362-1
Ubuntu 14.04

因為這台機器是CubieTruck,所以請選擇右邊 armhf 的網站,不同機器請選擇不同平台,

armhf

然後下載下方 bash-static_4.3-7ubuntu1.1_armhf.deb 和 bash_4.3-7ubuntu1.1_armhf.deb 這兩個檔案回來 CubieTruck,在終端機內使用 dpkg 來安裝

# dpkg -i bash-static_4.3-7ubuntu1.1_armhf.deb
# dpkg -i bash_4.3-7ubuntu1.1_armhf.deb
# apt-get update
# apt-get upgrade

安裝完之後再測試一次剛剛在終端機的命令

# env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

如果這次出現,

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test

那再次恭喜你,你已經把這個 CVE-2014-6271 漏洞給補起來了。這次升級會把 bash shell 從 4.3.8版升級為 4.3.11,但光看版號不準,要打命令測試才能確認。

如何防止WordPress暴力式登入攻擊

WordPress很容易遭受暴力式攻擊來試探密碼,其實也不只WordPress,所有的服務都怕,倒不是因為密碼強度不夠,而是怕這種無由來的暴力式攻擊會拖垮系統效能。像是 SSH 我取消了密碼登入,採用金鑰,而且一分鐘內登入不得超過三次,很快地暴力式攻擊就大幅減少了。

對於這種暴力式攻擊,如果第一時間發現,管理者可以採用 iptables 立刻把它給禁止連線,語法:

iptables -I INPUT -s 11.22.33.44 -j DROP
iptables -I OUTPUT -d 11.22.33.44 -j DROP

這鐵定立竿見影!但是如果你剛好不在身邊呢?我想到一個方法,就是根據上一篇文章提到的 如何幫Apache某個目錄加上帳號密碼保護,這次我們幫 wp-login.php 檔案加上密碼,這樣登入動作就會有兩次不同密碼防護,我相信暴力連線也可以大幅減少。

先到 wordpress 的目錄底下編輯 .htaccess 檔案,

# nano /var/www/wordpress/.htaccess

然後在這個檔案後面添上保護片段如下,

<Files wp-login.php>
AuthUserFile /etc/apache2/apache2.passwd
AuthName "Private access"
AuthType Basic
require user linaro
</Files>

這麼一來,想要登入執行 wp-login.php 時又得多一道密碼,我相信很多現成破解的程式就不管用了,而且兩道不同密碼,應該很夠用吧!

還有一種攻擊是專門試探 admin 密碼,即便 WordPress 已經取消管理者帳號非得 admin 了,但還是有很多機器人會來試探 admin 密碼,我們可以在你的佈景主題下的 functions.php 底下加入下面程式以避免:

add_filter( 'wp_authenticate', 'wpjam_no_admin_user' );
function wpjam_no_admin_user($user){
  if($user == 'admin'){
  exit;
  }
}

add_filter('sanitize_user', 'wpjam_sanitize_user_no_admin',10,3);
function wpjam_sanitize_user_no_admin($username, $raw_username, $strict){
  if($raw_username == 'admin' || $username == 'admin'){
  exit;
  }
  return $username;
}

這樣如果想要用 admin 登入 WordPress,登入畫面會變成空白頁。