Apache 是一款使用量排名第一的 web 服務器,LAMP 中的 A 指的就是它。因爲其開源、穩定、安全等特性而被普遍使用。前邊的一篇文章中已經記錄過如何搭建 LAMP 架構,搭建僅是第一步,其中最爲重要的就是 Apache 服務,也是 LAMP 的核心。下邊記錄了使用 Apache 以來常常用到的功能。javascript
Apache 一共有3種穩定的 MPM 模式(多進程處理模塊),它們分別是 prefork、worker、event。http-2.2版本的httpd默認的mpm工做模式爲prefork,2.4版本的httpd默認是event工做模式。能夠經過 httpd -V 來查看。php
[root@linuxblogs ~]# httpd -V | grep -i "server mpm" Server MPM: Prefork
編譯的時候,能夠經過 configure 的參數來指定:css
--with-mpm=prefork|worker|event
一、prefork 工做模式html
Apache在啓動之初,就預先fork一些子進程,而後等待請求進來。之因此這樣作,是爲了減小頻繁建立和銷燬進程的開銷。每一個子進程只有一個線程,在一個時間點內,只能處理一個請求。java
優勢:成熟穩定,兼容全部新老模塊。同時,不須要擔憂線程安全的問題。
缺點:一個進程相對佔用更多的系統資源,消耗更多的內存。並且,它並不擅長處理高併發請求。linux
二、worker 工做模式web
使用了多進程和多線程的混合模式。它也預先fork了幾個子進程(數量比較少),而後每一個子進程建立一些線程,同時包括一個監聽線程。每一個請求過來,會被分配到1個線程來服務。線程比起進程會更輕量,由於線程一般會共享父進程的內存空間,所以,內存的佔用會減小一些。在高併發的場景下,由於比起prefork有更多的可用線程,表現會更優秀一些。chrome
優勢:佔據更少的內存,高併發下表現更優秀。
缺點:必須考慮線程安全的問題。apache
三、event 工做模式vim
它和worker模式很像,最大的區別在於,它解決了keep-alive場景下,長期被佔用的線程的資源浪費問題。event MPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又容許它釋放。這樣加強了高併發場景下的請求處理能力。
HTTP採用keepalive方式減小TCP鏈接數量,可是因爲須要與服務器線程或進程進行綁定,致使一個繁忙的服務器會消耗完全部的線程。Event MPM是解決這個問題的一種新模型,它把服務進程從鏈接中分離出來。在服務器處理速度很快,同時具備很是高的點擊率時,可用的線程數量就是關鍵的資源限 制,此時Event MPM方式是最有效的,但不能在HTTPS訪問下工做。
有時候,咱們須要給一些特殊的訪問設置一個用戶認證機制,增長安全。好比咱們的我的網站,通常都是有一個管理後臺的,雖然管理後臺自己就有密碼,但咱們爲了更加安全,能夠再設置一層用戶認證。
一、編輯配置文件
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指定用戶密碼文件在哪裏。
二、建立加密用的用戶名和密碼文件
htpasswd -c /usr/local/apache2/htdocs/.htpasswd liwei htpasswd -m /usr/local/apache2/htdocs/.htpasswd admin
建立第一個用戶時-c選項建立.htpasswd文件,-m選項增長用戶,根據提示輸入密碼。
三、重啓apache服務
apachectl -t apachectl graceful
先檢查配置是否正確,而後用graceful至關因而reload配置,不用重啓apache服務,效果同樣。測試,經過瀏覽器輸入 www.123.com/admin.php 提示輸入密碼。
默認虛擬主機就是配置文件裏的第一個虛擬主機。關於默認虛擬主機有個特色,凡是解析到這臺服務器的域名,無論是什麼域名,只要在配置文件中沒有配置,那麼都會訪問到這個主機上來。若是咱們直接用IP訪問,會訪問到這個站點上來。爲了不別人亂解析,因此應該把默認也就是第一個虛擬主機給禁止掉。咱們使用allow,deny語句,已經禁止掉了。
一、配置默認虛擬主機
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
二、重啓apache服務器
apachectl -t apachectl graceful
若是用IP或其它解析的域名訪問,發現提示:
Forbidden
You don't have permission to access / on this server.
一個站點不免會有多個域名,而多個域名總得有一個主次,好比個人網站能夠用兩個域名訪問:www.itepub.cn 和 www.linuxblogs.cn 但你們發現無論我用哪一個域名訪問,最終都會跳轉到 www.linuxblogs.cn 上來。這個行爲就叫作域名跳轉,這裏的301只是一個狀態碼,跳轉除了301還有302,301是永久跳轉,302是臨時跳轉,網站上必定要設置爲301,這樣對搜索引擎是比較友好的。
一、配置域名跳轉
# vim /usr/local/apache2/conf/extra/httpd-vhosts.conf <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^www.abc.com$ RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
</IfModule>
配置爲:當訪問aaa時,跳轉到123的網站。
二、配置多個域名跳轉
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^www.abc.com$ [OR] RewriteCond %{HTTP_HOST} ^www.abcd.com$ RewriteRule ^/(.*)$ http://www.123.com/$1 [R=301,L]
</IfModule>
三、重啓服務器並測試
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/
Content-Type: text/html; charset=iso-8859-1
# 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有相關的配置,使日誌按照咱們的需求進行歸檔,好比天天一個新日誌,或者每小時一個新的日誌。
一、首先簡單設置日誌的路徑名稱
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
二、設置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等靜態對象。而這些文件的訪問每每是巨量的,並且即便記錄這些日誌也沒有什麼用,那麼如何忽略不記錄這些日誌呢?
一、配置日誌不記錄圖片的訪問
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,表示取反。
所說的靜態文件指的是圖片、js、css等文件,用戶訪問一個站點,其實大多數元素都是圖片、js、css等,這些靜態文件實際上是會被客戶端的瀏覽器緩存到本地電腦上的,目的就是爲了下次再請求時再也不去服務器上下載,這樣就加快了速度,提升了用戶體驗。但這些靜態文件總不能一直緩存,它總有一些時效性,那麼就得設置這個過時時間。
一、配置靜態緩存
# 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
二、重啓服務器並驗證
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
若是你的網站有不少漂亮的圖片,好比你網站域名 www.123.com,圖片地址爲 www.123.com/image/111.jpg,那麼其它人就能夠直接把這個地址放到他本身的網站上,他的用戶能夠直接從他網站查看這張圖片,而實際圖片是從你的網站訪問的,所產生的帶寬消耗對你沒有任何意義,應該對這些圖片限制一下,凡是在第三方站點上,嚴禁訪問你站點的圖片,如何配置呢?
一、配置防盜鏈
# 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是根據來源連接作限制的,若是來源連接不是咱們想要的,就直接拒絕,這就是防盜鏈的原理。固然不止是圖片,mp三、rar、zip等文件一樣支持。上述配置中默認是除了定義的列表中的referer,其它都拒絕。
其實咱們能夠對apache的訪問進行控制,能夠設置白名單或黑名單。前面更改httpd.conf時候就已經看到了allow,deny這兩個關鍵詞,先來看看allow和deny的規則。
一、舉例1
Order deny,allow deny from all allow from 127.0.0.1
咱們的判斷依據是這樣的:
二、舉例2
Order allow,deny deny from all allow from 127.0.0.1
這個就會deny全部了,127.0.0.1也會被deny。由於順序是先allow而後deny,雖然開始allow了127,可是後面又拒絕了它。
三、舉例3
Order allow,deny
deny from all
上面的規則就表示,所有都不能經過。
四、舉例4
Order deny,allow
deny from all
上面的規則表示,所有都不能通。
Order deny,allow
只有順序,沒有具體規則,表示所有均可以通行(默認的),由於allow在最後了。
Order allow,deny
這個表示,所有都不能通行(默認的),由於deny在最後。
五、針對某個目錄限制
好比這個目錄很重要,只容許咱們公司的IP訪問,固然這個目錄能夠是網站根目錄,也就是整個站點。
<Directory /usr/local/apache2/htdocs> Order deny,allow Deny from all Allow from 127.0.0.1
</Directory>
六、針對請求的URL去限制
<filesmatch "(.*)admin(.*)"> Order deny,allow Deny from all Allow from 127.0.0.1
</filesmatch>
這裏用到了filesmatch語法,表示匹配的意思。
七、驗證
# 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
<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叫作瀏覽器標識,目前主流的瀏覽器有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://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/ 字樣的請求都限制了。
^_^...... 差很少到這裏就要結束了,之後有新的經常使用功能再來更新。