Apache 是一款使用量排名第一的 web 服務器,LAMP 中的 A 指的就是它。由於其開源、穩定、安全等特性而被廣泛使用。前邊的一篇文章中已經記錄過如何搭建 LAMP 架構,搭建僅是第一步,其中最爲重要的就是 Apache 服務,也是 LAMP 的核心。下邊記錄了使用 Apache 以來經常用到的功能。
一、Apache的三種工作模式
Apache 一共有3種穩定的 MPM 模式(多進程處理模塊),它們分別是 prefork、worker、event。http-2.2版本的httpd默認的mpm工作模式爲prefork,2.4版本的httpd默認是event工作模式。可以通過 httpd -V 來查看。
[root@linuxblogs ~]# httpd -V | grep -i "server mpm"
Server MPM: Prefork
編譯的時候,可以通過 configure 的參數來指定:
--with-mpm=prefork|worker|event
1、prefork 工作模式
Apache在啓動之初,就預先fork一些子進程,然後等待請求進來。之所以這樣做,是爲了減少頻繁創建和銷燬進程的開銷。每個子進程只有一個線程,在一個時間點內,只能處理一個請求。
優點:成熟穩定,兼容所有新老模塊。同時,不需要擔心線程安全的問題。
缺點:一個進程相對佔用更多的系統資源,消耗更多的內存。而且,它並不擅長處理高併發請求。
2、worker 工作模式
使用了多進程和多線程的混合模式。它也預先fork了幾個子進程(數量比較少),然後每個子進程創建一些線程,同時包括一個監聽線程。每個請求過來,會被分配到1個線程來服務。線程比起進程會更輕量,因爲線程通常會共享父進程的內存空間,因此,內存的佔用會減少一些。在高併發的場景下,因爲比起prefork有更多的可用線程,表現會更優秀一些。
優點:佔據更少的內存,高併發下表現更優秀。
缺點:必須考慮線程安全的問題。
3、event 工作模式
它和worker模式很像,最大的區別在於,它解決了keep-alive場景下,長期被佔用的線程的資源浪費問題。event MPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又允許它釋放。這樣增強了高併發場景下的請求處理能力。
HTTP採用keepalive方式減少TCP連接數量,但是由於需要與服務器線程或進程進行綁定,導致一個繁忙的服務器會消耗完所有的線程。Event MPM是解決這個問題的一種新模型,它把服務進程從連接中分離出來。在服務器處理速度很快,同時具有非常高的點擊率時,可用的線程數量就是關鍵的資源限 制,此時Event MPM方式是最有效的,但不能在HTTPS訪問下工作。
二、Apache的用戶認證
有時候,我們需要給一些特殊的訪問設置一個用戶認證機制,增加安全。比如我們的個人網站,一般都是有一個管理後臺的,雖然管理後臺本身就有密碼,但我們爲了更加安全,可以再設置一層用戶認證。
1、編輯配置文件
vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
在對應的虛擬主機配置中加入如下配置:(加粗部分是添加內容)
<VirtualHost *:80>
DocumentRoot "/usr/local/apache2/htdocs"
ServerName www.123.com
ServerAlias www.abc.com
<Directory /usr/local/apache2/htdocs/admin.php>
AllowOverride AuthConfig
AuthName "Please input you acount."
AuthType Basic
AuthUserFile /usr/local/apache2/htdocs/.htpasswd
require valid-user
</Directory>
</VirtualHost>
說明:首先指定要對哪個目錄進行驗證,AuthName自定義,AuthUserFile指定用戶密碼文件在哪裏。
2、創建加密用的用戶名和密碼文件
htpasswd -c /usr/local/apache2/htdocs/.htpasswd liwei
htpasswd -m /usr/local/apache2/htdocs/.htpasswd admin
創建第一個用戶時-c選項創建.htpasswd文件,-m選項增加用戶,根據提示輸入密碼。
3、重啓apache服務
apachectl -t
apachectl graceful
先檢查配置是否正確,然後用graceful相當於是reload配置,不用重啓apache服務,效果一樣。測試,通過瀏覽器輸入 www.123.com/admin.php 提示輸入密碼。
三、設置默認虛擬主機
默認虛擬主機就是配置文件裏的第一個虛擬主機。關於默認虛擬主機有個特點,凡是解析到這臺服務器的域名,不管是什麼域名,只要在配置文件中沒有配置,那麼都會訪問到這個主機上來。如果我們直接用IP訪問,會訪問到這個站點上來。爲了避免別人亂解析,所以應該把默認也就是第一個虛擬主機給禁止掉。我們使用allow,deny語句,已經禁止掉了。
1、配置默認虛擬主機
vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
添加一個虛擬主機的記錄:
<VirtualHost *:80>
DocumentRoot "/var/123"
ServerName xxxxx.com.cn
<Directory /var/123>
Order allow,deny
Deny from all
</Directory>
</VirtualHost>
創建/var/123目錄,並且設置600權限,daemon用戶無法訪問:
mkdir /var/123
chmod -R 600 /var/123
2、重啓apache服務器
apachectl -t
apachectl graceful
如果用IP或其它解析的域名訪問,發現提示:
Forbidden
You don't have permission to access / on this server.
四、域名301跳轉
一個站點難免會有多個域名,而多個域名總得有一個主次,比如我的網站可以用兩個域名訪問:www.itepub.cn 和 www.linuxblogs.cn 但大家發現不管我用哪個域名訪問,最終都會跳轉到www.linuxblogs.con 上來。這個行爲就叫做域名跳轉,這裏的301只是一個狀態碼,跳轉除了301還有302,301是永久跳轉,302
是臨時跳轉,網站上一定要設置爲301,這樣對搜索引擎是比較友好的。
1、配置域名跳轉
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.abc.com$
RewriteRule ^/(.*)$ http:<span>//www.123.com/$1 [R=301,L]
</IfModule>
配置爲:當訪問aaa時,跳轉到123的網站。
2、配置多個域名跳轉
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.abc.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.abcd.com$
RewriteRule ^/(.*)$ http:<span>//www.123.com/$1 [R=301,L]
</IfModule>
3、重啓服務器並測試
apachectl -t
apachectl graceful
測試:
# curl -x192.168.0.8:80 www.abc.com -I
HTTP/1.1 301 Moved Permanently
Date: Tue, 25 Oct 2016 15:48:10 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Location: http://www.123.com/
# curl -x192.168.0.8:80 www.abcd.com -I
HTTP/1.1 301 Moved Permanently
Date: Tue, 25 Oct 2016 15:48:49 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Location: http://www.123.com/
Content-Type: text/html; charset=iso-8859-1
通過上述測試,發現無論是abc或abcd都可以跳轉到 www.123.com 域名上來,通過瀏覽器訪問也一樣。
五、Apache日誌切割
我們每訪問一次網站,那麼就會記錄若干條日誌。當然前提是已經設置了日誌,日誌不去管理,時間長了日誌文件會越來越大,如何避免產生這麼大的日誌文件?其實apache有相關的配置,使日誌按照我們的需求進行歸檔,比如每天一個新日誌,或者每小時一個新的日誌。
1、首先簡單設置日誌的路徑名稱
vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
編輯添加內容如下:
ErrorLog "logs/error.log"
CustomLog "logs/access.log" combined
指定了日誌存放在/usr/local/apache2/logs目錄下分別爲error.log和access.log,combined爲日誌顯示的格式,日誌格式可以參考配置文件httpd.conf中格式的指定,如下:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
2、設置apache日誌分割
同樣編輯配置文件httpd-vhosts.conf
ErrorLog "|/usr/local/apache2/bin/rotatelogs -l /usr/local/apache2/logs/aaa-error_%Y%m%d.log 86400"
CustomLog "|/usr/local/apache2/bin/rotatelogs -l /usr/local/apache2/logs/aaa-access_%Y%m%d.log 86400" combined
ErrorLog是錯誤日誌,CustomLog是訪問日誌。|就是管道符,意思是把產生的日誌交給rotatelog這個工具,而這個工具就是apache自帶的切割日誌的工具。-l的作用是校準時區爲UTC,也就是北京時間。86400,單位是秒,正好是一天,那麼日誌會每天切割一次。而最後面的combined爲日誌的格式,在httpd.conf中有定義。
六、不記錄指定文件類型的日誌
如果一個網站訪問量特別大,那麼訪問日誌就會很多,但有一些訪問日誌我們其實是可以忽略掉的,比如網站的一些圖片,還有js、css等靜態對象。而這些文件的訪問往往是巨量的,而且即使記錄這些日誌也沒有什麼用,那麼如何忽略不記錄這些日誌呢?
1、配置日誌不記錄圖片的訪問
vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
相關配置爲:
SetEnvIf Request_URI ".*\.gif$" image-request
SetEnvIf Request_URI ".*\.jpg$" image-request
SetEnvIf Request_URI ".*\.png$" image-request
SetEnvIf Request_URI ".*\.bmp$" image-request
SetEnvIf Request_URI ".*\.swf$" image-request
SetEnvIf Request_URI ".*\.js$" image-request
SetEnvIf Request_URI ".*\.css$" image-request
CustomLog "|/usr/local ... _%Y%m%d.log 86400"
combined env=!image-request
說明:在原來日誌配置基礎上,增加了一些image-request的定義,比如把gif、jpg、bmp、swf、js、css等結尾的全標記爲image-request,然後在配置日誌後加一個標記env=!image-request,表示取反。
七、Apache配置靜態緩存
所說的靜態文件指的是圖片、js、css等文件,用戶訪問一個站點,其實大多數元素都是圖片、js、css等,這些靜態文件其實是會被客戶端的瀏覽器緩存到本地電腦上的,目的就是爲了下次再請求時不再去服務器上下載,這樣就加快了速度,提高了用戶體驗。但這些靜態文件總不能一直緩存,它總有一些時效性,那麼就得設置這個過期時間。
1、配置靜態緩存
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/gif "access plus 1 days"
ExpiresByType image/jpeg "access plus 24 hours"
ExpiresByType image/png "access plus 24 hours"
ExpiresByType text/css "now plus 2 hour"
ExpiresByType application/x-javascript "now plus 2 hours"
ExpiresByType application/javascript "now plus 2 hours"
ExpiresByType application/x-shockwave-flash "now plus 2 hours"
ExpiresDefault "now plus 0 min"
</IfModule>
或者使用 mod_headers 模塊實現:
<IfModule mod_headers.c>
# htm,html,txt 類的文件緩存一個小時
<filesmatch "\.(html|htm|txt)$">
header set cache-control "max-age=3600"
</filesmatch>
# css, js, swf 類的文件緩存一個星期
<filesmatch "\.(css|js|swf)$">
header set cache-control "max-age=604800"
</filesmatch>
# jpg,gif,jpeg,png,ico,flv,pdf 等文件緩存一年
<filesmatch "\.(ico|gif|jpg|jpeg|png|flv|pdf)$">
header set cache-control "max-age=29030400"
</filesmatch>
</IfModule>
說明:這裏的時間單位可以 days、 hours 甚至是 min,兩種不同的方法,上面使用的是mod_expires,而下面用的是 mod_headers,要想使用這些模塊,必須要事先已經支持。如何查看是否支持,使用命令:
# /usr/local/apache2/bin/apachectl -M
2、重啓服務器並驗證
apachectl -t
apachectl graceful
驗證:
# curl -x127.0.0.1:80 'http://www.123.com/static/image/common/online_admin.gif' -I
HTTP/1.1 200 OK
Date: Wed, 26 Oct 2016 03:51:26 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Last-Modified: Tue, 31 May 2016 03:08:36 GMT
ETag: "46891b-16b-5341ab0597500"
Accept-Ranges: bytes
Content-Length: 363
Cache-Control: max-age=86400
Expires: Thu, 27 Oct 2016 03:51:26 GMT
Content-Type: image/gif
八、Apache配置防盜鏈
如果你的網站有很多漂亮的圖片,比如你網站域名 www.123.com,圖片地址爲 www.123.com/image/111.jpg,那麼其它人就可以直接把這個地址放到他自己的網站上,他的用戶可以直接從他網站查看這張圖片,而實際圖片是從你的網站訪問的,所產生的帶寬消耗對你沒有任何意義,應該對這些圖片限制一下,凡是在第三方站點上,嚴禁訪問你站點的圖片,如何配置呢?
1、配置防盜鏈
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
SetEnvIfNoCase Referer "^http://.*\.123\.com" local_ref
SetEnvIfNoCase Referer ".*\.abc\.com" local_ref
SetEnvIfNoCase Referer "^$" local_ref
<filesmatch "\.(txt|doc|mp3|zip|rar|jpg|gif)">
Order Allow,Deny
Allow from env=local_ref
</filesmatch>
說明:在這段配置中涉及到一個名詞referer,其實就是上次訪問的網站鏈接。配置referer是根據來源鏈接做限制的,如果來源鏈接不是我們想要的,就直接拒絕,這就是防盜鏈的原理。當然不止是圖片,mp3、rar、zip等文件同樣支持。上述配置中默認是除了定義的列表中的referer,其它都拒絕。
九、Apache訪問控制
其實我們可以對apache的訪問進行控制,可以設置白名單或黑名單。前面更改httpd.conf時候就已經看到了allow,deny這兩個關鍵詞,先來看看allow和deny的規則。
1、舉例1
Order deny,allow
deny from all
allow from 127.0.0.1
我們的判斷依據是這樣的:
- 看Order後面的,哪個在前,哪個在後
- 如果deny在前,那麼就需要看deny from這句,然後看allow from這句
- 規則是一條一條匹配的,不管是deny在前還是allow在前,都會生效的。
2、舉例2
Order allow,deny
deny from all
allow from 127.0.0.1
這個就會deny所有了,127.0.0.1也會被deny。因爲順序是先allow然後deny,雖然開始allow了127,但是後面又拒絕了它。
3、舉例3
Order allow,deny
deny from all
上面的規則就表示,全部都不能通過。
4、舉例4
Order deny,allow
deny from all
上面的規則表示,全部都不能通。
Order deny,allow
只有順序,沒有具體規則,表示全部都可以通行(默認的),因爲allow在最後了。
Order allow,deny
這個表示,全部都不能通行(默認的),因爲deny在最後。
5、針對某個目錄限制
比如這個目錄很重要,只允許我們公司的IP訪問,當然這個目錄可以是網站根目錄,也就是整個站點。
<Directory /usr/local/apache2/htdocs>
Order deny,allow
Deny from all
Allow from 127.0.0.1 </Directory>
6、針對請求的URL去限制
<filesmatch "(.*)admin(.*)">
Order deny,allow
Deny from all
Allow from 127.0.0.1
</filesmatch>
這裏用到了filesmatch語法,表示匹配的意思。
7、驗證
# curl -x192.168.0.8:80 www.123.com/admin.php -I
HTTP/1.1 403 Forbidden
Date: Wed, 26 Oct 2016 06:24:54 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
Content-Type: text/html; charset=iso-8859-1
# curl -x127.0.0.1:80 www.123.com/admin.php -I
HTTP/1.1 401 Authorization Required
Date: Wed, 26 Oct 2016 06:25:03 GMT
Server: Apache/2.2.31 (Unix) PHP/5.5.38
WWW-Authenticate: Basic realm="Please input you acount."
Content-Type: text/html; charset=iso-8859-1
十、禁止解析PHP
某個目錄下禁止解析PHP,這個很有作用,我們做網站安全的時候,這個用的很多,比如某些目錄可以上傳文件,爲了避免上傳的文件有木馬,所以我們禁止這個目錄下面的訪問解析PHP。
1、配置禁止解析php
<Directory /usr/local/apache2/htdocs/data>
php_admin_flag engine off
<filesmatch "(.*)php">
Order deny,allow
Deny from all
</filesmatch>
</Directory>
說明:php_admin_flag engine off這個語句就是禁止解析php的控制語句,但只這樣配置還不夠,因爲這樣配置後用戶依然可以訪問php文件,只不過不解析了,但可以下載,用戶下載php文件也是不合適的,所以有必要再禁止一下。
十一、禁止指定user_agent
user_agent叫做瀏覽器標識,目前主流的瀏覽器有IE、chrome、Firefox、360、iphone的Safari、Android手機上的、百度搜索引擎、google搜索引擎等很多,每一種瀏覽器都有對應的user_agent。爲了避免一些無用的搜索引擎或機器爬蟲之類引起的帶寬的無辜消耗。
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.abc.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.abcd.com$
RewriteRule ^/(.*)$ http:<span>//www.123.com/$1 [R=301,L]
RewriteCond %{HTTP_USER_AGENT} ".*Firefox.*" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ".*Tomato Bot.*" [NC]
RewriteRule .* - [F]
</IfModule>
同樣是使用rewrite模塊來實現限制指定user_agent。本例中,RewriteRule .* – [F]可以直接禁止訪問,rewritecond用user_agent來匹配,NC表示不區分大小寫,OR表示或者,連接下一個條件。假如我們要把百度的搜索引擎限制掉,可以加一條這樣的規則:
RewriteCond %{HTTP_USER_AGENT} ^.*Baiduspider/2.0.* [NC]
RewriteRule .* - [F]
十二、限制某個目錄
我們可以allow和deny去現在網站根目錄下的某個子目錄,當然這個rewrite也可以實現,配置如下:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^.*/tmp/* [NC]
RewriteRule .* - [F]
</IfModule>
這段配置,會把只要是包含 /tmp/ 字樣的請求都限制了。
此爲張大神原創,轉載請自覺註明:
轉載請註明來自張辰雲的個人網站-雲編碼Note,本文地址:http://www.itzcy.com/blog/1299.html
除非註明,張辰雲的個人網站-雲編碼Note文章均爲原創,轉載請註明出處和鏈接!
除非註明,張辰雲的個人網站-雲編碼Note文章均爲原創,轉載請註明出處和鏈接!