實際環境
- 系統環境
macOS Sierra(10.12.5)
- Apache
Apache/2.4.25 (Unix)
- OpenSSL
OpenSSL 1.0.2l
引言
Mac系統默認安裝了Apache服務器,你只需要在終端里輸入sudo apachectl start
命令,然后打開瀏覽器,輸入網址http://localhost/index
,顯示如下圖:
恭喜你,一個HTTP服務器已經搭建成功了!是不是很簡單?接下來介紹如何具體定制化配置Apache服務器。
搭建HTTP服務器
-
修改服務器默認根路徑
打開配置文件/private/etc/apache2/httpd.conf
,更改系統默認的根路徑DocumentRoot
為自定義路徑(因為系統默認的根路徑要求管理員權限,更改比較繁瑣,如果需要用系統默認的根路徑,可以跳過此步驟)。
DocumentRoot "/Users/libo/apache_server"
<Directory "/Users/libo/apache_server">
-
設置虛擬主機
通過設置多個虛擬主機可以支持一臺物理服務器訪問多個域名,就好像有多個服務器一樣。打開配置文件/private/etc/apache2/httpd.conf
,去掉#Include /private/etc/apache2/extra/httpd-vhosts.conf
前面的#
,保存并退出。然后打開/private/etc/apache2/extra/httpd-vhosts.conf
,注釋掉以下代碼:
#<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host.example.com
# DocumentRoot "/usr/docs/dummy-host.example.com"
# ServerName dummy-host.example.com
# ServerAlias www.dummy-host.example.com
# ErrorLog "/private/var/log/apache2/dummy-host.example.com-error_log"
# CustomLog "/private/var/log/apache2/dummy-host.example.com-access_log" common
#</VirtualHost>
#<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host2.example.com
# DocumentRoot "/usr/docs/dummy-host2.example.com"
# ServerName dummy-host2.example.com
# ErrorLog "/private/var/log/apache2/dummy-host2.example.com-error_log"
# CustomLog "/private/var/log/apache2/dummy-host2.example.com-access_log" common
#</VirtualHost>
然后加入以下代碼:
<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "/Users/libo/apache_server/mywebsite"
ServerName mywebsite.com
ErrorLog "/private/var/log/apache2/mywebsite.com-error_log"
CustomLog "/private/var/log/apache2/mywebsite.com-access_log" common
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/Users/libo/apache_server/mywebsite2"
ServerName mywebsite2.com
ErrorLog "/private/var/log/apache2/mywebsite2.com-error_log"
CustomLog "/private/var/log/apache2/mywebsite2.com-access_log" common
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
我們也配置兩個虛擬主機,因為HTTP不顯式指定訪問端口號時默認為80號端口,為了訪問方便,我們設置服務器訪問端口號為80,當然你也可以設置其它端口號,比如8080,這時還需要配置httpd.conf
,加入Listen 8080
。但有些端口有特殊意義,不能隨便設置,比如443端口號默認是HTTPS訪問端口。
<Directory /></Directory>
之間的配置是一些比較細化的服務器配置選項,AllowOverride all
是允許覆蓋所有的文件,Order deny,allow
是命令的兩種類型,Allow from all
是允許所有的客戶端(或代理)訪問本服務器,你也可以配置
Allow from #IP
或Deny from #IP
來控制允許或者禁止特定的IP訪問服務器。
注意:兩個虛擬主機的根路徑必須在服務器根路徑下。
-
更改本地DNS配置文件
打開配置文件/private/etc/hosts
,把我們的服務器域名對應到回送地址127.0.0.1
上,這樣就可以直接本地進行域名訪問。文件前3行配置是系統默認配置,我們平時訪問的localhost
就是通過該文件直接解析成對應的IP地址進行本地訪問的,其中127.0.0.1
是IPv4
標準,::1
是IPv6
標準。其實我們平時通過域名訪問網址時,都會首先訪問這個本地的hosts
文件來查找IP地址,如果找不到對應的結果才會訪問DNS服務器進行DNS解析來進行后續的步驟。
配置代碼如下:
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 mywebsite.com
127.0.0.1 mywebsite2.com
-
驗證
最后我們在配置的服務器根路徑下加入測試的HTML文件來進行測試,結果如下:
說明我們的HTTP服務器已經配置成功了!
搭建HTTPS服務器
我們只需要在HTTP服務器的基礎上配置HTTPS就可以了。
-
創建自簽名SSL/TLS證書
首先使用OpenSSL創建私鑰文件
openssl genrsa -out mywebsite.key 2048
然后利用私鑰創建自簽名證書
openssl req -new -x509 -key mywebsite.key -out mywebsite.cer
需要自己填寫一些證書信息,如下圖:
紅框標注選項最好填寫虛擬主機域名,如果不按要求填寫也可以使用,同理我們創建另一個虛擬主機mywebsite2.com證書。
修改服務器配置
去掉#Include /private/etc/apache2/extra/httpd-ssl.conf
前面的#
,
去掉#LoadModule ssl_module libexec/apache2/mod_ssl.so
前面的#
,
去掉#LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
前面的#
。修改httpd-ssl.conf配置
打開/private/etc/apache2/extra/httpd-ssl.conf
文件,找到對應的SSLCertificateFile
和SSLCertificateKeyFile
字段,加入如下代碼:
SSLCertificateFile "/Users/libo/apache_server/mywebsite/mywebsite.cer"
SSLCertificateFile "/Users/libo/apache_server/mywebsite2/mywebsite2.cer"
SSLCertificateKeyFile "/Users/libo/apache_server/mywebsite/mywebsite.key"
SSLCertificateKeyFile "/Users/libo/apache_server/mywebsite2/mywebsite2.key"
-
修改虛擬主機配置
更改虛擬主機默認端口號為443
,配置服務器證書SSLCertificateFile
和私鑰SSLCertificateKeyFile
,如下:
<VirtualHost *:443>
# ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "/Users/libo/apache_server/mywebsite"
ServerName mywebsite.com
ErrorLog "/private/var/log/apache2/mywebsite.com-error_log"
CustomLog "/private/var/log/apache2/mywebsite.com-access_log" common
SSLCertificateFile "/Users/libo/apache_server/mywebsite/mywebsite.cer"
SSLCertificateKeyFile "/Users/libo/apache_server/mywebsite/mywebsite.key"
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:443>
# ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/Users/libo/apache_server/mywebsite2"
ServerName mywebsite2.com
ErrorLog "/private/var/log/apache2/mywebsite2.com-error_log"
CustomLog "/private/var/log/apache2/mywebsite2.com-access_log" common
SSLCertificateFile "/Users/libo/apache_server/mywebsite2/mywebsite2.cer"
SSLCertificateKeyFile "/Users/libo/apache_server/mywebsite2/mywebsite2.key"
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
-
驗證
重啟服務器sudo apachectl restart
,瀏覽器訪問,如下圖:
可以看到我們的HTTPS服務器已經搭建成功了,盡管不是“安全”的訪問!接下來我們要進行一些操作使訪問變得“安全”。
-
創建安全的HTTPS訪問
所謂創建安全的HTTPS訪問,就是讓瀏覽器信任服務器頒發的公鑰證書,因為我們的證書沒有添加到瀏覽器信任列表,所以瀏覽器會提示我們“不安全”。廢話不多說,首先創建CA根證書:
創建CA私鑰:
openssl genrsa -des3 -out Apache_CA.key 2048
這里使用-des3進行加密,需要4~1023位密碼。
創建CA證書:
openssl req -new -x509 -days 365 -key Apache_CA.key -out Apache_CA.cer
這里需要輸入剛才設置的CA私鑰密碼并填寫一些證書信息。
創建服務器證書私鑰:
openssl genrsa -out mywebsite.key 2048
生成證書請求文件CSR:
openssl req -new -key mywebsite.key -out mywebsite.csr
這里同樣需要填寫一些證書信息,同樣,紅框標注選項最好填寫虛擬主機域名。
生成證書配置文件v3.ext:
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = mywebsite.com
DNS.1
要寫配置證書的服務器域名。
用自己的CA簽發證書:
openssl x509 -req -in mywebsite.csr -CA Apache_CA.cer -CAkey Apache_CA.key -CAcreateserial -out mywebsite.cer -days 365 -sha256 -extfile v3.ext
然后需要輸入生成Apache_CA.key時設置的密碼。
恭喜你,證書已經創建成功!然后我們按照前面提到的步驟替換掉服務器的證書,重啟服務器sudo apachectl restart
。
設置系統始終信任CA證書:
雙擊點開Apache_CA.cer
,然后在鑰匙串中找到該證書,右鍵->顯示簡介->信任
,設置為始終信任。然后分別再次訪問網址https://mywebsite.com/index
和https://mywebsite2.com/index
。訪問結果如下:
恭喜你!mywebsite.com
服務器的訪問已經變成“安全”的了,同理可以配置mywebsite2.com
服務器。但是,你要注意一點,這種“安全”只是相對的安全,或者說是一種假象,因為你的CA證書是自己創建頒發的,別人也可以通過竊取你的CA私鑰或者其他方式來偽造證書。更為穩妥的辦法還是要向正規的證書頒發機構去申請私鑰和證書,這點一定要注意。
搭建正向代理服務器
在搭建正向代理服務器之前,我們先說下正向代理和反向代理的區別。我們平時訪問網上的資源,絕大多數情況是要經過各種(正向或反向或其他)代理的,只是這對用戶來說是無感知的。正向代理可以理解為一層跳板,我們訪問資源的目的IP地址是服務器,只是經過正向代理這個節點。而反向代理是我們訪問資源的目的IP地址就是反向代理服務器,反向代理服務器和最終的服務器進行交互,獲取資源。下圖可以很清晰的展示這兩種關系:
下面我們開始配置正向代理服務器。
-
修改服務器配置
打開配置文件/private/etc/apache2/httpd.conf
,去掉以下module
前面的#
。
#LoadModule proxy_module libexec/apache2/mod_proxy.so
#LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so
#LoadModule proxy_ftp_module libexec/apache2/mod_proxy_ftp.so
#LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
通過以上module
的命名我們可以了解到mod_proxy.so
是基礎的代理配置,mod_proxy_http.so
支持HTTP
請求,mod_proxy_ftp.so
支持FTP
請求,mod_proxy_connect.so
支持HTTPS
請求(HTTPS
請求頭和報文是加密的,代理服務器不能通過識別請求頭來獲取目的服務器的地址,所以在最開始建立連接時代理服務器需要打開一條從客戶端到服務器的端到端connect
通道)。
-
修改虛擬主機配置
將虛擬主機端口號改為80
,加入正向代理設置。
<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "/Users/libo/apache_server/mywebsite"
ServerName mywebsite.com
ErrorLog "/private/var/log/apache2/mywebsite.com-error_log"
CustomLog "/private/var/log/apache2/mywebsite.com-access_log" common
SSLCertificateFile "/Users/libo/apache_server/mywebsite/mywebsite.cer"
SSLCertificateKeyFile "/Users/libo/apache_server/mywebsite/mywebsite.key"
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order deny,allow
Allow from all
</Directory>
#正向代理設置
ProxyRequests On
ProxyVia Full
<Proxy *>
Order deny,allow
#Deny from all
Allow from all
</Proxy>
</VirtualHost>
ProxyVia Full
可以為我們打出最詳細的代理服務器信息。
-
創建自動代理配置
為了方便測試,我們創建mywebsite.pac
文件來配置代理。
function FindProxyForURL(url, host) {
if (host == "www.lxweimin.com") {
return "PROXY 127.0.0.1:80";
}
return 'DIRECT;';
}
我們有選擇的只要求訪問簡書www.lxweimin.com
域名時經過我們的代理服務器,其他域名進行DIRECT
直連。
配置代理配置
打開系統偏好設置->網絡->高級->代理,選中自動代理配置,配置mywebsite.pac
文件的路徑地址,然后點擊好->應用。驗證
瀏覽器打開簡書首頁http://www.lxweimin.com/
,打開開發者模式:
通過Via
字段,我們發現這次請求經過了我們的代理服務器,說明我們的配置成功了!
搭建反向代理服務器
修改服務器配置
我們需要用PHP
腳本來測試反向代理,Apache
服務器自身支持PHP
,只需要打開配置文件/private/etc/apache2/httpd.conf
,去掉#LoadModule php5_module libexec/apache2/libphp5.so
前面的#
。修改虛擬主機配置
我們把mywebsite.com
和mywebsite2.com
的默認端口號改為80
,讓mywebsite2.com
作為反向代理服務器,mywebsite.com
作為原始服務器,通過訪問反向代理服務器間接訪問原始服務器資源。配置代碼如下:
<VirtualHost *:80>
# ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/Users/libo/apache_server/mywebsite2"
ServerName mywebsite2.com
ErrorLog "/private/var/log/apache2/mywebsite2.com-error_log"
CustomLog "/private/var/log/apache2/mywebsite2.com-access_log" common
SSLCertificateFile "/Users/libo/apache_server/mywebsite2/mywebsite2.cer"
SSLCertificateKeyFile "/Users/libo/apache_server/mywebsite2/mywebsite2.key"
<Directory />
Options Indexes FollowSymLinks MultiViews
AllowOverride all
Order deny,allow
Allow from all
</Directory>
#反向代理設置
ProxyPass / http://mywebsite.com/
ProxyPassReverse / http://mywebsite.com/
</VirtualHost>
ProxyPass / http://mywebsite.com/
是把所有訪問當前主機http://mywebsite2.com/
的請求轉發給http://mywebsite.com/
主機,至于ProxyPassReverse / http://mywebsite.com/
的作用,我們稍后再說。
-
驗證
我們在"/Users/libo/apache_server/mywebsite"
路徑下創建兩個PHP
文件:
redirect.php
<?php
function redirect($url)
{
header("Location: $url");
exit();
}
$url = "http://mywebsite.com/test.php";
redirect($url);
?>
test.php
<?php
phpinfo();
?>
重啟服務器,訪問http://mywebsite2.com/redirect.php
。
可以看到請求的Request URL
的host
還是mywebsite2.com
,但是它確實是由 mywebsite.com
來處理的,通過訪問mywebsite.com
資源redirect.php
文件,進而重定向到test.php
文件。說明我們反向代理服務器已經搭建成功了!
現在我們介紹下ProxyPassReverse
的作用,我們把配置文件的這一項配置去掉,重啟服務器再次訪問http://mywebsite2.com/redirect.php
。
和上圖對比可以看到請求的Request URL
的host
是mywebsite.com
而不是 mywebsite2.com
,這是因為配置了ProxyPassReverse
后,mywebsite.com/redirect.php
在重定向到mywebsite.com/test.php
時,Apache會將它調整回 mywebsite2.com/test.php
, 然后Apache再將mywebsite2.com/test.php
轉發給mywebsite.com/test.php
。所以說配置了ProxyPassReverse
后,即使在請求過程中發生了重定向,Apache也會幫你擦去這些痕跡。
總結
以上都是我對Apache
服務器的基礎配置,簡單的實現了預期功能。服務器配置很細碎繁瑣,能根據不同代碼實現更為復雜精細的配置,更為詳細的功能具體請參考官方文檔,本人沒有做深入研究。本文如有錯誤,希望指正,一起學習,共同進步,不勝感激!
參考鏈接
http://www.liuchungui.com/blog/2015/09/25/zi-jian-zheng-shu-pei-zhi-httpsfu-wu-qi/
http://beyondvincent.com/2014/03/17/2014-03-17-five-tips-for-using-self-signed-ssl-certificates-with-ios/
http://www.cnblogs.com/zemliu/archive/2012/04/18/2454655.html
http://httpd.apache.org/docs/2.4/