在CubieTruck下限制特定使用者才能執行 su

之前使用 Slackware Linux Distribution時,可以限定某些使用者方可執行 su,轉變成 root。到了 Ubuntu,怎麼預設值是任意使用者都可以執行 su 轉換成 root,這看起來有點危險。所以我要在 Ubuntu 修改一下讓只有某些特定使用者才能執行 su。

首先,我發現到 Ubuntu 連 wheel 這個族群都沒有了,所以得在 /etc/group 下複製一個 wheel 族群。

# nano /etc/group

然後在第一行 root 下,添加一行一樣group id=0的 wheel 使用者族群,讓它看起來像是

root:x:0:root
wheel:x:0:root

然後存檔,這個檔案之後我們還要再改改。然後到 /etc/pam.d 目錄下找到 su 這個檔案,然後編輯它。

# nano /etc/pam.d/su

然後找到下面這一行

# auth       required   pam_wheel.so deny group=nosu

把它改成為

auth required pam_wheel.so group=wheel

存檔後不需要重啟機器或是任何服務,然後回到剛剛的 /etc/group 檔案裡面,把你要的特定人士加到 wheel 這個群族裡面,看起來像是

wheel:x:0:root,user1,user2

存檔後,只有user1user2才能通過su密碼認證,其他使用者即便密碼正確,也無法轉換成 root。

Ubuntu系統開啟 ufw 防火牆之後,iptables -A 和 -I的差異

今天在用 iptables 設定每個IP限制幾個連線時,來回好幾次怎麼設定都不能正常運作,正在納悶到底是怎麼一回事時,我把 -A 的參數改成 -I 之後竟然正常了。所以打算追根究柢看看到底哪裡出了什麼問題了。我們先說說這個命令好了,

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

一個簡單的 iptables 命令,限制每個 IP 只能 10 個 HTTP 連線,超過就丟棄封包不理它。無奈怎麼都不會正常運作,索性改成

iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

嘿,竟然正常了。根據 iptables 語法,-A代表是Append附加在既有規則上,-I則是代表Insert添加在最前面,所以我就把整個 iptables 規則 dump 出來看看

# iptables-save > ~/rules

一看規則,明白了,雖然兩行的命令是一樣的,但順序不一樣。一個在 ufw 前面,一個在 ufw 後面。

-A INPUT -p tcp -m tcp --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-sa
(上面的規則是 -I添加進來的)
...
...
...
-A INPUT -j ufw-before-logging-input
-A INPUT -j ufw-before-input
-A INPUT -j ufw-after-input
-A INPUT -j ufw-after-logging-input
-A INPUT -j ufw-reject-input
-A INPUT -j ufw-track-input
-A INPUT -p tcp -m tcp --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-sa
(上面的規則是 -A附加進來的)
...
...

我們知道 iptables 運作規定是由上往下執行,很顯然的,如果採用 -I,因為是添加在最前面,所以運作規則會在 ufw 之前。反之如果採用 -A,那麼附加的規則會在 ufw 之後。但是 ufw 之前已經設定

# ufw allow 80

所以按照 iptables 執行順序,只要是 80 port 的都會被 ufw 允許,所以 -A 添加的規則根本不會執行到,那當然運作就不正常了。而 -I 的命令則在 ufw 之前,所以才能先過濾掉,然後才交給 ufw 判斷,唉,浪費了不少時間。

如何增加 SSH 登入前警告提示

SSH是系統中最重要的服務之一,很多伺服器的命令都是透過 SSH 終端機完成的,所以很多人都想趁機登入 SSH 以取得最大權限,真的防不勝防。所以我打算在登入之前提示一些警告提示

首先在 /etc/ 目錄下編輯 issue.net 這個檔案

# nano /etc/issue.net

寫入自己想要的提示警告,例如

###############################################################
#                   Welcome to CubieTruck's World             #
#                                                             #
#      Only Non-Root and Password-less key login allowed      #
###############################################################

存檔後到 /etc/ssh 目錄下編輯 sshd_config 檔案

# nano /etc/ssh/sshd_config

把這一行 # 注釋移除掉

Banner /etc/issue.net

存檔後就可以重啟 ssh 服務即可。

# service ssh restart

這樣登入前就可以看到一些警示標語了。

在 CubieTruck 上安裝 GeoIP 取得 IP 位址地理位置

每天看 log,都會看到一堆 IP 位址想要來入侵 CubieTruck 小系統,但都不知道這些 IP 位址到底是位於何方?所以只能安裝 GeoIP 套件來反查其地理位置。首先來安裝套件

# apt-get install geoip-bin

然後就可以輸入 ip 位置反查

# geoiplookup 61.174.51.215
GeoIP Country Edition: CN, China

這樣就可以大約查出他的位置是從中國來的(果然不出所料),但如果要更深入一點知道在中國哪裡,那你得下載更完整的資料庫,

GeoIP下載位置

下載完解壓縮之後你可以得到一個約18MB大小的 GeoLiteCity.dat 的資料庫,先把它放在自己的家目錄裡面(或是放在 /usr/share/GeoIP 目錄也行 )。之後用這個資料庫再來反查

# geoiplookup -f ~/GeoLiteCity.dat 61.174.51.215
GeoIP City Edition, Rev 1: CN, 02, Zhejiang, Huzhou, N/A, 30.870300, 120.093300, 0, 0

你就可以更正確知道這個 61.174.51.215 IP位址是從中國浙江省湖州市來的,經緯度是在 30.870300, 120.093300附近。

CubieTruck簡易式阻擋DDoS防禦方式

DDoS是一種討厭的攻擊方式,駭客會在短時間內利用建立新連線方式阻擋他人連線的一種攻擊手法。這種攻擊手法相當難防禦,殊不見各大Server常常碰到此類型跳板式的DDoS攻擊,所以這裡用iptables做一個最簡易的防禦方式。

iptables -N WEB_SRV_DOS
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j WEB_SRV_DOS
iptables -A WEB_SRV_DOS -p tcp --syn -m multiport --dports 80,443 -m recent --rcheck --second 20 --hitcount 100 -j LOG --log-prefix "[Possible DOS Attack]"
iptables -A WEB_SRV_DOS -p tcp --syn -m multiport --dports 80,443 -m recent --rcheck --second 20 --hitcount 100 -j REJECT
iptables -A WEB_SRV_DOS -p tcp --syn -m multiport --dports 80,443 -m recent --set
iptables -A WEB_SRV_DOS -p tcp -m multiport --dports 80,443 -j ACCEPT

上面這段會把80/443(HTTP/HTTPS)Port新連線記錄下,最近20秒內如果想要建立連線超過100次,則會記錄下來並且丟棄封包進而阻擋DoS,因為  hitcount 超過 20,所以請參考這一篇文章來加大 xt_recent 的數值,以方便偵測。

如何限制CubieTruck對某個IP對HTTP Port只能有一定量的連線數目

CubieTruck是一台很小的伺服器,裡面的配備與資源相當陽春,所以經不起很多人同時連線,更遑論要阻擋DDoS了,所以我打算要用 iptables 來限制某個IP對HTTP/HTTPS Port只能有限定數量的連線,超過這個數目就丟棄封包不理會,算是一種最陽春的DDoS的阻擋了吧!

HTTP 80 Port,只要同一個IP超過10個連線就丟棄封包。

iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

HTTPS 443 Port,只要同一個IP超過10個連線就丟棄封包。

iptables -I INPUT -p tcp --dport 443 -m connlimit --connlimit-above 10 -j REJECT

但如果你的 Apache 服務器掛載很多種引擎,例如 ownCloud私有雲,常用來上傳和下載檔案,那這個數字 10 要自己拿捏好,不要阻擋了自己合法連線而拖慢速度。

另外,還有一點必須考量的是,這個被限制的IP位址可能是某個Proxy Server的IP位址,意味著Proxy Server後面可能有很多的電腦在後面,那麼10個連線就有點太少了。

如何在 Ubuntu 下使用 mod_evasive 防止 Apache HTTP的DDoS

DDoS是一種阻斷式攻擊,可以在短時間內透過大量的連線來妨礙其他人無法取得伺服器的服務,對於一個伺服器來說,這是一場夢靨。幸好,Apache2有一個 mod_evasive 套件可以幫你阻絕 DDoS,並且擁有大量的數值可以讓你微調。

首先我們可以透過 apt-get install 來安裝此套件。

# apt-get install libapache2-mod-evasive

安裝完之後在 /etc/apache2/mods-enabled 目錄下多出兩個檔案,evasive.confevasive.load檔案,尤其evasive.conf是可以微調這些選項的組態檔案,內容為:

選項 解釋
DOSHashTableSize 處理雜湊表的大小,越大所需記憶體越大,需根據網站流量狀況來設定,建議流量越大,此數值就需要越大。
DOSPageCount 在DOSPageInterval所設定的時間內,同一個來源 IP 位址 存取同一個頁面的最大存取次數。
DOSSiteCount 在DOSSiteInterval所設定的時間內,同一個來源 IP 位址可同時發出 HTTP 存取的最大次數。
DOSPageInterval 設定 DOSPageCount 的時間區段,以秒為單位。
DOSSiteInterval 設定 DOSSiteCount 的時間區段,以秒為單位。
DOSBlockingPeriod 當某一IP 位址違反上述的DOSPageCount/DOSPageInterval或DOSSiteCount/DOSSiteInterval,將被block的秒數。
DOSmailNotify 管理者的 Email 位址,當有某個IP位址被阻斷時,會寄發警告信至此信箱中。
DOSSystemCommand 當發現有疑似攻擊,立即自動執行的指令。
DOSLogdir mod_evasive 的記錄檔位置,如果沒設定此值,預設存放記錄 的目錄為 /tmp。當有疑似攻擊時,會在該目錄下新增一個 dos_[ip] 的檔案。

然後把 /etc/apache2/mods-enabled/evasive.conf檔案的#去除掉之後填上自己所需要的數值,然後重新啟動 apache2 服務即可。

# service apache2 restart

但是要注意,如果你自己也安裝 ownCloud 私有雲的話,很有可能系統 ownCloud 會在短時間內上傳或是下載小的檔案,這就有可能會被 mods-evasive誤認為是一種DDoS行為而拒絕服務,所以裡面的數值自己要拿捏好,不然可能自己的 ownCloud 這一類程式會運作不正常。

在 Ubuntu 下如何增大 iptables 的 rt_recent 記錄表格大小

最近在研究如何使用 iptables 限制每個 IP 位址每分鐘可以連線多少次,以避免有人利用DDOS進行服務阻斷攻擊。但是發現不是出現錯誤訊息(使用 dmesg 觀看錯誤訊息),就是根本無法工作正常,錯誤訊息如下:

xt_recent: hitcount (200) is larger than packets to be remembered (20)

在網路上查了一下發現原來系統 iptables 也是有限制的,例如 Ubuntu 作業系統預設值是只能記錄最近的 100 個 IP 位址,而每個 IP 只能記錄最近的 20 筆記錄,所以你要 iptables 記錄最近 200 筆資料已經遠遠超出它可以記錄的預設值 20 筆了。而這些數值都在 /sys/module/xt_recent/parameters 目錄底下的,ip_list_tot (記錄最近幾個 IP位址),和 ip_pkt_list_tot(每個IP位址記錄最近的幾個封包)。

/sys/module/xt_recent/parameters/ip_list_tot = 100 --> 所以只能記錄最近 100 個 IP 位址
/sys/module/xt_recent/parameters/ip_pkt_list_tot = 20 --> 所以只能記錄每個IP位址最近 20 個封包

如果要更改這些設定,我找了很久,因為Linux版本很多,我尚無一個明確的方法,更糟糕的是這兩個虛擬檔案預設值只能讀取,不能寫入。所以還必須更改其寫入權限,所以我把它寫到 /etc/rc.local ,讓系統一開機時就可以更改。

# nano /etc/rc.local

在檔案尾部增加

chmod 600 /sys/module/xt_recent/parameters/ip_list_tot
chmod 600 /sys/module/xt_recent/parameters/ip_pkt_list_tot
echo "200" > /sys/module/xt_recent/parameters/ip_list_tot
echo "200" > /sys/module/xt_recent/parameters/ip_pkt_list_tot

這樣每次開機時就可以使 iptables 記錄 200 個 IP 位址,每個 IP 位址可以記錄 200 個封包記錄,但是這肯定會增加記憶體用量以及 CPU 的負載,所以副作用還不得而知,先試試看。建議各位不要設定太大!

我有看過核心 Kernel 編譯時的一些參數,這兩個數值不要超過 255,不然可能導致系統崩潰。而且此方法只能適用在 Ubuntu,其他的版本尚無驗證過!

如何防範 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 地址。

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,但光看版號不準,要打命令測試才能確認。