1. 程式人生 > 其它 >使用Apache服務部署靜態網站

使用Apache服務部署靜態網站

網站服務程式

網站的粗略定義:讓使用者能夠通過瀏覽器訪問到的伺服器上的文件資源。

網站服務就是Web網路服務,一般是指允許使用者通過瀏覽器訪問到網際網路中各種資源的服務。

Web網路服務是一種被動訪問的服務程式,即只有接收到網際網路中其他主機發出的請求後才會響應,最終用於提供服務程式的Web伺服器會通過HTTP(超文字傳輸協議)或HTTPS(安全超文字傳輸協議)把請求的內容傳送給使用者。

常見能提供Web網路服務的程式:IIS(只能在Windows系統中使用)、Apache、Nginx等。

部署Apache程式:

1 yum install httpd #安裝Apache服務程式(Apache服務的軟體包名為httpd)
2 systemctl start httpd #啟用httpd服務
3 systemctl enable httpd #加入開機啟動項

用瀏覽器訪問:127.0.0.1(本機)可以看到httpd服務程式的預設頁面,當看到這個頁面時,說明服務程式正常啟動,但有以下可能性導致沒有顯示本應顯示的網站內容:

1.許可權不足
2.網站內沒有資料

配置服務檔案引數

httpd服務程式的主要配置檔案及存放位置:

服務目錄 /etc/httpd
主配置檔案 /etc/httpd/conf/httpd.conf
網站資料目錄 /var/www/html
訪問日誌 /var/log/httpd/access_log
錯誤日誌 /var/log/httpd/error_log

在httpd服務程式的主配置檔案中,存在三種類型的資訊:註釋行資訊、全域性配置、區域配置。全域性配置引數與區域配置引數的區別:

全域性配置:一種全域性性的配置引數,可作用於對所有的子站點,既保證了子站點的正常訪問,也有效減少了頻繁寫入重複引數的工作量。
區域配置:單獨針對於每個獨立的子站點進行設定。

在httpd服務程式主配置檔案中,最為常用的引數最常用的引數以及用途描述:

ServerRoot 服務目錄
ServerAdmin 管理員郵箱
User 執行服務的使用者
Group 執行服務的使用者組
ServerName 網站伺服器的域名
DocumentRoot 網站資料目錄
Listen 監聽的IP地址與埠號
DirectoryIndex 預設的索引頁頁面
ErrorLog 錯誤日誌檔案
CustomLog 訪問日誌檔案
Timeout 網頁超時時間,預設為300秒

DocumentRoot引數用於定義網站資料的儲存路徑,其引數的預設值是把網站資料存放到/var/www/html目錄中;而當前網站普遍的首頁面名稱是index.html,因此可以向/var/www/html目錄中寫入名為index的html檔案,替換掉httpd服務程式的預設首頁面,該操作會立即生效。

例項:修改儲存網站資料的目錄。

1 #1.建立新的網站資料儲存目錄,並建立首頁檔案。
2 mkdir /home/wwwroot
3 echo "hello" > /home/wwwroot/index.html
4 #2.修改httpd服務程式主配置檔案,把網站資料儲存路徑修改為/home/wwwroot
5 vim /etc/httpd/conf/httpd.conf
6 ...
7 119 DocumentRoot "/home/wwwroot" #用於定義網站資料儲存路徑的引數DocumentRoot修改為/home/wwwroot
8 ...
9 124 <Directory "home/wwwroot"> #用於定義目錄許可權的引數Directory後面的路徑也修改為/home/wwwroot
10 ...
11 128
12 ...
13 #3.重啟httpd服務驗證效果,此時會發現因為許可權不足導致出現的是httpd預設首頁(SElinux的安全上下文).
14 systemctl restart httpd
15 #4.暫時禁用SElinux,發現可以看到正常的網頁內容了。
16 setenforce 0

SELinux安全子系統

RHEL 7系統使用SELinux技術的目的是為了讓各個服務程序都受到約束,使其僅獲取到本應獲取的資源。

SELinux安全子系統能夠從多方面監控違法行為:對服務程式的功能進行限制(SELinux域限制可以確保服務程式做不了出格的事情);對檔案資源的訪問限制(SELinux安全上下文確保檔案資源只能被其所屬的服務程式進行訪問)。

“SELinux域”和“SELinux安全上下文”是Linux系統中的雙保險,系統內的服務程式只能規規矩矩地拿到自己所應該獲取的資源,這樣即便黑客入侵了系統,也無法利用系統內的服務程式進行越權操作。

SELinux服務有三種配置模式:

enforcing:強制啟用安全策略模式,將攔截服務的不合法請求。
permissive:遇到服務越權訪問時,只發出警告而不強制攔截。
disabled:對於越權的行為不警告也不攔截。

雖然在禁用SELinux服務後確實能夠減少報錯機率,但這在生產環境中相當不推薦。

SELinux服務主配置檔案:/etc/selinux/config。其中的SELINUX引數定義的就是SELinux的預設配置模式。注意其為系統重啟後的狀態,不會再更改後立即生效。

1 vim /etc/selinux/config
2 ...
3 SELINUX=enforcing
4 ...

檢視和設定SELinux服務執行命令:

getenforce:檢視當前SELinxu服務的執行模式

setenforce [0|1]:修改SELinux當前的執行模式(0禁用,1啟用)。此修改是臨時的,在系統重啟後就會失效。

分析上面例項被SELinux攔截的原因:

httpd服務程式的功能是允許使用者訪問網站內容,因此SELinux會預設放行使用者對網站的請求操作。但是,/home目錄是用來存放普通使用者的家目錄資料的,而將網站資料的預設儲存目錄修改為了/home/wwwroot,導致httpd提供的網站服務要去獲取普通使用者家目錄中的資料,這顯然違反SELinux的監管原則。

semanage命令:用於管理SELinux的策略,格式:semanage [選項] [檔案]。

semanage命令不僅能夠像傳統chcon命令那樣—設定檔案、目錄的策略,還可以管理網路埠、訊息介面。常用引數:

-l:用於查詢;
-a:用於新增;
-m:用於修改;
-d:用於刪除;
-t:指定要想修改的值。

semanage命令沒有遞迴功能,因此要先修改目錄的安全上下文,再修改目錄裡所有檔案的安全上下文。另外semanage命令修改好的配置不會立即生效。

restorecon命令:將設定好的SELinux安全上下文立即生效。格式: restorecon [選項] [指定目錄或檔案]。

常用引數:

-R:對指定目錄進行遞迴操作
-v:顯示SELinux安全上下文的修改過程

例項:解決上面例項被SELinux攔截的問題。

1 #1.把SELinux服務恢復到強制啟用安全策略模式
2 setenforce 1
3 #2.分別檢視原始網站資料的儲存目錄與當前網站資料的儲存目錄的SELinux安全上下文值
4 ls -Zd /var/www/html #SElinux安全上下文為httpd_sys_content_t
5 ls -Zd /home/wwwroot #SELinux安全上下文為home_root_t
6 #3.把當前網站資料儲存目錄的安全上下文設定成和原始網站資料儲存目錄的安全上下文一樣
7 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot #修改目錄的安全上下文
8 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/* #修改目錄裡的所有檔案的安全上下文
9 #4.使設定好的SELinux安全上下文立即生效
10 restorecon -Rv /home/wwwroot/

個人使用者主頁功能

如果想在系統中為每位使用者建立一個獨立的網站,若採用基於虛擬網站主機功能來部署多個網站的方法,會累死管理員,而且在使用者自行管理網站時,還會碰到各種許可權限制,費時費力。

httpd服務程式提供的個人使用者主頁功能可以讓系統內所有的使用者在自己的家目錄中管理個人的網站,而且訪問起來也非常容易。

getsebool命令:搭配-a引數輸出所有安全策略(off禁止,on允許)
setsebool命令:修改SELinux策略中各條規則的布林值。搭配-P引數使得修改後的SELinux策略規則立即且永久生效。

例項:實現個人使用者主頁功能。

1 #1.修改配置檔案/etc/httpd/conf.d/userdir.conf ,讓httpd服務程式開啟個人使用者主頁功能。
2 vim /etc/httpd/conf.d/userdir.conf
3 ...
4 17 UserDir public_html #UserDir引數表示網站資料在使用者家目錄中的儲存目錄名稱,即public_html目錄
5 ...
6 31 <Directory "/home/*/public_html"> #注意要和17行的目錄名一致
7 ...
8 35
9 #2.在使用者家目錄中建立用於儲存網站資料的目錄及首頁檔案。把自己家目錄的許可權修改為755,以保證其他人也有許可權讀取裡面的內容。退出該使用者。
10 su - linuxprobe
11 mkdir public_html #注意要和配置檔案中的目錄名一致
12 echo "linuxprobe's website" > public_html/index.html
13 chmod -Rf 755 ~ #“~”代表就是當前使用者的家目錄,相當於/home/linuxprobe
14 exit
15 #3.重啟httpd服務。在瀏覽器輸入網址驗證(格式:網址/~使用者名稱),會報錯。原因依然在於SELinux。
16 systemctl restart httpd
17 #4.查詢並過濾出所有與http協議相關的安全策略。留意httpd_enable_homedirs是否為on狀態,若不是,修改為on狀態並立即且永久生效。
18 getsebool -a | grep http
19 setsebool -P httpd_enable_homedirs=on

自己探究出來的一個很重要的點:上面的個人使用者網站資料目錄public_html,可以是其他名字,只要確保配置檔案中的兩處地方,以及使用者在家目錄建立網站資料目錄的名字保持一致就行了。不過,需要注意,使用者在家目錄建立的目錄名字如果不是public_html,那麼該目錄的預設安全上下文就不會是httpd_user_content_t,也就會被SElinux所攔截(至於為什麼只有名字是public_html,其安全上下文才會預設為httpd_user_content_t,這個就不清楚了)。所以這種情況的解決辦法:

1.怎麼方便怎麼來,目錄的名字還是public_html比較省事;
2.非要取一個自己喜歡的目錄名稱,在上面例項的基礎之上,確保目錄及裡面的所有檔案的安全上下文為httpd_user_content_t,若不是就修改。

例項:在上面例項的基礎上,為網站中新增口令功能,讓只有通過身份驗證的使用者訪客才能看到網站內容。

htpasswd命令:建立和更新儲存使用者名稱、密碼的文字檔案, 用於對HTTP使用者的basic認證。htpasswd 是開源 http 伺服器apache httpd的一個命令工具。其中,用於驗證的使用者名稱稱不必是系統已有的本地賬戶,該命令生成的賬戶密碼和系統中的賬戶密碼是獨立的,沒有聯絡。

-c引數:建立密碼檔案.如果密碼檔案已經存在,那麼它會重新寫入並刪去原有內容。

1 #1.生成密碼資料庫
2 htpasswd -c /etc/httpd/passwd liwh #生成密碼檔案,新增一個名為liwh的使用者
3 htpasswd /etc/httpd/passwd liangjm #往密碼檔案追加一個使用者liangjm
4 #2.修改個人使用者主頁功能的配置檔案
5 vim /etc/httpd/conf.d/userdir.conf
6 ...
7 31 <Directory "/home/*/public_html">
8 32 AllowOverride all #允許偽靜態技術
9 33 authuserfile "/etc/httpd/passwd" #指定生成的密碼檔案的存放路徑
10 34 authname "Fuck you" #當用戶嘗試訪問個人使用者網站時的提示資訊
11 35 authtype basic #採用基本驗證方式
12 36 require user linagjm #指定使用者進行賬戶密碼認證時支援驗證的使用者(可以支援多個使用者驗證,比如:liangjm,liwh)
13 37
14 #3.重啟httpd服務,重新整理頁面,會彈出視窗要求輸入賬戶密碼。其中liwh的帳號密碼是沒用的,只能用liangjm賬號密碼驗證
15 systemctl restart httpd

虛擬網站主機功能

Apache的虛擬主機功能是伺服器基於使用者請求的不同IP地址、主機域名或埠號,實現提供多個網站同時為外部提供訪問服務的技術。

在配置虛擬網站主機功能前,做些基本設定:

分別在/home/wwwroot中建立用於儲存不同網站資料的3個目錄,並向其中分別寫入網站的首頁檔案。每個首頁檔案中要有明確區分不同網站內容的資訊,以便能更直觀地檢查效果。由前面例項可知,目錄/home/wwwroot及其下級目錄和檔案一定會受到SELinux安全上下文的制約,要修改相關內目錄及其裡面所有檔案的SELinux安全上下文,並讓設定立即生效。

1 mkdir -p /home/wwwroot/A
2 mkdir -p /home/wwwroot/B
3 mkdir -p /home/wwwroot/C
4 echo "This is A" > /home/wwwroot/A/index.html
5 echo "This is B" > /home/wwwroot/B/index.html
6 echo "This is C" > /home/wwwroot/C/index.html
7 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
8 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/A
9 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/B
10 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/C
11 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/A/*
12 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/B/*
13 semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/C/*
14 restorecon -Rv /home/wwwroot

例項1:基於IP地址實現虛擬網站主機功能。

1 #1.為網絡卡配置3個ip地址(方法很多)
2 vim /etc/sysconfig/network-scripts/ifcfg-eno16777728
3 ...
4 IPADDR0=192.168.10.10
5 IPADDR1=192.168.10.20
6 IPADDR2=192.168.10.30
7 ...
8 #2.編輯httpd服務的主配置檔案,追加寫入3個基於IP地址的虛擬主機網站引數
9 vim /etc/httpd/conf/httpd.conf
10 ...
11 113 <VirtualHost 192.168.10.10> #虛擬主機引數開始
12 114 DocumentRoot /home/wwwroot/B #虛擬主機的家目錄
13 115 ServerName www.b.com #虛擬主機的域名
14 116 <Directory /home/wwwroot/B > #子目錄許可權指定
15 117 AllowOverride None #關閉偽靜態
16 118 Require all granted #允許所有環回請求
17 119
18 120 #虛擬主機引數結束
19 121 <VirtualHost 192.168.10.10>
20 122 DocumentRoot /home/wwwroot/A
21 123 ServerName www.a.com
22 124 <Directory /home/wwwroot/A >
23 125 AllowOverride None
24 126 Require all granted
25 127
26 128
27 129 <VirtualHost 192.168.10.30>
28 130 DocumentRoot /home/wwwroot/C
29 131 ServerName www.c.com
30 132 <Directory /home/wwwroot/C >
31 133 AllowOverride None
32 134 Require all granted
33 135
34 136
35 ...
36 #3.重啟httpd服務,在瀏覽器分別輸入相應的ip地址進行驗證。
37 systemctl restart httpd

結果:

訪問192.168.10.30,會出現“This is C”;
訪問192.168.10.20,會出現預設頁面(因為上面根本沒有用到192.168.10.20);
訪問192.168.10.10,會出現“This is B”。上面配置引數表明192.168.10.10這個ip地址是對應著兩個虛擬主機網站引數,但是由於B頁面的引數編輯在最上面,因此訪問192.168.10.10時出現的是B頁面。

例項2:在例項1的基礎之上,基於主機域名實現虛擬網站主機功能。

1 #1.編輯IP地址與域名之間對應關係的配置檔案,儲存退出後會立即生效
2 vim /etc/hosts
3 ...
4 192.168.10.10 www.a.com www.b.com www.c.com
5 ...

基於主機域名的配置其實在例項1就已經配置好了,因為是基於主機域名,所以和ip地址無關。輸入虛擬主機裡定義的域名,就會出現相對應的頁面。

分別在瀏覽輸入相應的域名,結果:

訪問www.a.com,出現“This is A”;
訪問www.b.com,出現“This is B”;
訪問www.c.com,出現“This is C”;

例項3:在例項1的基礎上,基於埠號實現虛擬網站主機功能。

1 #1.修改httpd服務的主配置檔案,新增幾個用於監聽埠的引數;修改虛擬主機網站引數為基於埠號的形式。
2 vim /etc/httpd/conf/httpd.conf
3 ...
4 43 Listen 6111 #監聽埠6111引數
5 44 Listen 6222
6 45 Listen 6333
7 ...
8 113 <VirtualHost 192.168.10.10:6111> #基於埠的虛擬主機網站引數
9 ...
10 121 <VirtualHost 192.168.10.10:6222>
11 ...
12 129 <VirtualHost 192.168.10.10:6333>
13 ...
14 #2.檢視SELinux是否允許Apache服務使用新新增的幾個監聽埠,若不允許則新增這些埠號
15 semanage port -l | grep http #使用semanage命令查詢並過濾出所有與HTTP協議相關且SELinux服務允許的埠列表。
16 semanage port -a -t http_port_t -p tcp 6111 #在SELinux允許的與HTTP協議相關的埠號中新增相應的埠號
17 semanage port -a -t http_port_t -p tcp 6222
18 semanage port -a -t http_port_t -p tcp 6333
19 semanage port -l | grep http #新增埠號的操作會立即且永久生效,再一次檢視與HTTP協議相關且SELinux服務允許的埠列表。
20 #3.重啟httpd服務
21 systemctl restart httpd

測試結果:

訪問192.168.10.10:6111,顯示“This is B”。
訪問192.168.10.10:6222,顯示“This is A”。
訪問192.168.10.10:6333,顯示“This is C”。

Apache的訪問控制

Apache可以基於源主機名、源IP地址或源主機上的瀏覽器特徵等資訊對網站上的資源進行訪問控制。它通過Allow指令允許某個主機訪問伺服器上的網站資源,通過Deny指令實現禁止訪問。在允許或禁止訪問網站資源時,還會用到Order指令。

apache會按照order決定最後使用哪一條規則,比如“Order allow,deny”,雖然會優先匹配allow規則,但由於在order中allow不是最後規則,還需要看有沒有deny規則。根據這個邏輯,有可能出現先允許所有人訪問,但最後的deny規則禁止了A訪問,最終的結果就是A無法訪問。注意,order決定的“最後”規則非常重要。

例項:設定Apache訪問控制,使得只有ip地址為192.168.10.1或使用火狐瀏覽器的客戶端才能訪問指定的網頁。

1 #1.在預設網站資料目錄新建一個子目錄,並在該子目錄建立一個首頁檔案。
2 mkdir /var/www/html/server
3 echo "NB" > /var/www/html/server/index.html
4 #2.修改httpd服務的主配置檔案,編輯規則限制源主機的訪問。
5 vim /etc/httpd/conf/httpd.conf
6 ...
7 129 <Directory "/var/www/html/server"> #針對該子目錄的許可權設定
8 130 SetEnvIf User-Agent "Firefox" ff=1 #設定環境變數,相當於ff="使用者通過Firefox訪問"
9 131 Order allow,deny #先匹配允許規則再匹配拒絕規則
10 132 Deny from 192.168.10.55 #拒絕ip地址為192.168.10.55的主機訪問
11 133 Allow from env=ff #允許使用火狐瀏覽器的人訪問
12 134 Allow from 192.168.10.1 #允許ip地址192.168.10.1的主機訪問
13 135
14 ...
15 #3.重啟httpd服務
16 systemctl restart httpd

測試結果:

ip地址為192.168.10.1的主機使用非火狐瀏覽器也能訪問;
ip地址為192.168.10.55的主機即使使用火狐瀏覽器也不能訪問;
ip地址不是192.168.10.1的主機使用火狐瀏覽器可以訪問。