如何縮短網路連結關閉時間

我們使用 netstat 指令觀看網路連結時候,常常會看到一堆 TIME_WAIT 的 socket 等待被關閉,而這些 socket 必須等待一段時間後才會被釋放重新被使用,底下是一張 TCP 完整的機制圖(state machine)。

1

一般而言,網路 socket 關閉時比建立時還要複雜很多,原因很多,其中一個是等待 keepalive 再次送訊息來,但是事實上很多時候 socket 是可以被關閉了,所以會有很多 TIME_WAIT 的 socket 殘留在系統中,這一篇我們來說說怎麼修改這些時間,縮短時間,好讓這些 socket 被釋放讓系統可以重新使用。

在 Linux 裡面,這些參數都不是寫死在系統裡面,相反的而是在 /proc/sys/net/ipv4 虛擬檔案目錄裡面,在 /etc/sysctl.conf 裡面可以有其對應的數值,只要修改這個數值,socket 結束的等待時間就可以被改變了。

# nano /etc/sysctl.conf

在檔案後面增加

net.ipv4.netfilter.ip_conntrack_generic_timeout = 120
net.ipv4.tcp_tw_recycle = 1 ; socket 可以重新被使用
net.ipv4.tcp_tw_reuse = 1 ; socket 可以重新被使用
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 180
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120
net.ipv4.tcp_keepalive_intvl = 30 ; 預設值是75,建議在15-30秒內
net.ipv4.tcp_keepalive_probes = 5 ; 預設值是9,建議可以試探5次即可。
net.ipv4.tcp_timestamps = 0 
net.ipv4.tcp_sack = 1 
net.ipv4.tcp_window_scaling = 1

這些數值都是可以修改的,是有關於 socket 的狀態時限的。修改完可以輸入下面命令立刻生效。重新開機後也會自動被載入。

# sysctl -p

注意:每個系統都有其獨特性,所以上面數值僅供參考。一般而言,我們當伺服器的話,當然希望無用的 socket 趕快結束重新可以被使用,相反的如果是當做桌機,這些數值就沒有那麼敏感了。

如何增大 Apache 上傳檔案大小限制

之前架設 ownCloud 時,雖然 ownCloud 已經把上傳檔案大小限制改為 512MB,但是有時候還是上傳不了,後來查了一下原來在 PHP5裡面是有限制的,必須修改一下,設定檔案在 /etc/php5/apache2/php.ini 裡面。

# nano /etc/php5/apache2/php.ini

找到下面兩行,改成你要的檔案大小,

upload_max_filesize = 512M ;預設值是 2M
post_max_size= 512M ;預設值是 2M

然後重新啟動 Apache2 服務即可。

# service apache2 restart

如何取消 CubieTruck IPv6 的功能

雖然去年已經正式啟動了 IPv6 的協議,但是這台 CubieTruck 我估計用到除役前,IPv6也還不會流行,所以索性把它給取消了,取消的方法很簡單,在 /etc/ 目錄下的 sysctl.conf 有一些設定

# nano /etc/sysctl.conf

在這個檔案後面增加

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.br0.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.wlan0.disable_ipv6 = 1

然後再命令中輸入

# sysctl -p

讓它立刻生效即可!然後在 /etc/modprobe.d 目錄下編輯 blacklist.conf 檔案

# nano /etc/modprobe.d/blacklist.conf

然後在檔案後面增加一行

blacklist ipv6

然後重新開機方能生效。如果要查看是否真的取消 IPv6功能,則可以在命令列輸入

# ip a | grep inet6

如果沒有任何輸出文字,那就代表你真的取消了 IPv6 的功能了。

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 系統下微調網路參數

現在台灣光纖到府(FTTH/FTTB)十分普遍,雙向100M也不是天方夜譚了,所以理論上在網路傳送上可以採用比較大的緩衝區來傳遞,但是 Ubuntu 的預設值是給普羅大眾使用的,一般人可能是用 ADSL,或是更慢的撥接上網,所以 Ubuntu 在傳送的預設值是 128KB。因為筆者的網路是光纖到府,所以我就微調一下這些數值為512KB,讓傳送可以快一點。 但是理論上必須根據你自己的網路頻寬去做調整,我這裡只是作個筆記,把我自己的設定值列出來而已,並不對裡面的數值作任何解釋,而且也許會對你的系統造成副作用。 這個參數檔案在 /etc/sysctl.conf 裡面,

# nano /etc/sysctl.conf

在這個檔案後面加入

net.core.rmem_default = 524288 # default is 163840 
net.core.rmem_max = 524288 # default is 131071
net.core.wmem_default = 524288 # default is 163840
net.core.wmem_max = 524288 # default is 131071
net.ipv4.tcp_wmem = 4096 87380 524288 # default is 4096 16384 4194304
net.ipv4.tcp_rmem = 4096 87380 524288 # default is 4096 87380 6165056

然後輸入

# sysctl -p

就可以立刻生效,如果要看是否有設定成功可以輸入

# sysctl -a | grep rmem

看看數值是否是自己設定的數值相符合。

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

如何將 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 服務。