
我想做一個這樣的虛擬主機:
<VirtualHost *:80 *:443>
<IfPort 443>
SSLEngine On
...
</IfPort>
...
</VirtualHost>
因此,如果主機已透過連接埠 443 訪問,我想添加一些額外的功能。我可以以某種方式實現這一目標,還是必須將其分成 2 個虛擬主機?
答案1
我用來mod_macro
在託管大量不同網域的伺服器上解決這個問題...安裝模組(每個作業系統/發行版有所不同),然後配置如下:
LoadModule macro_module libexec/apache22/mod_macro.so
<Macro VHost $host>
<VirtualHost *:80>
DocumentRoot /usr/local/www/$host/data
ServerName $host
ServerAlias *.$host
ScriptAlias /cgi-bin/ "/usr/local/www/$host/cgi-bin/"
IncludeOptional etc/apache22/vhosts/$host
</VirtualHost>
</Macro>
<Macro VHostSSL $host>
<VirtualHost *:80>
DocumentRoot /usr/local/www/$host/data
ServerName $host
ServerAlias *.$host
ScriptAlias /cgi-bin/ "/usr/local/www/$host/cgi-bin/"
IncludeOptional etc/apache22/vhosts/$host
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /usr/local/www/$host/data
ServerName $host
ServerAlias *.$host
SSLEngine on
SSLCertificateFile /usr/local/www/$host/ssl/$host.crt
SSLCertificateKeyFile /usr/local/www/$host/ssl/$host.key
ScriptAlias /cgi-bin/ "/usr/local/www/$host/cgi-bin/"
IncludeOptional etc/apache22/vhosts/$host
</VirtualHost>
</Macro>
Use VHostSSL example.com
Use VHost example.net
新增域名超簡單;任何特定於域的配置都會被丟到包含檔案中。
答案2
使用約翰的解決方案我得到了這個
Apache 2 is starting ...
AH00526: Syntax error on line 53 of .../httpd-vhosts.conf:
SSLEngine not allowed here
正如約翰所說,最好的方法是擁有2 個虛擬主機;但我的虛擬主機程式碼超過150 行(大量反向代理),因為我不想每個程式碼都有2 個(以及一個很長的設定檔)我最終做了這個有效的事情:
1.為非ssl虛擬主機建立虛擬主機。
2.建立另一個虛擬主機並反向代理到第一個虛擬主機
<VirtualHost *:443>
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "...cert.crt"
SSLCertificateKeyFile "...server.ssl.key"
... (any ssl specific config)
ProxyPreserveHost On
ProxyPass / http://localhost:80/
ProxyPassReverse http://localhost:80/ http://yourdomain.com/
</VirtualHost>
這根本不是一個好的或效能友善的解決方案,但如果不需要2 個虛擬主機的原因是為了防止所有虛擬主機配置有2 個版本(這意味著每次您想要更改某些內容時更改2行),那麼這是可行的。
答案3
避免重複的另一個選擇是將虛擬主機配置保留在特定檔案中,並透過包含將其拉入:
/etc/path/to/config/example.com.conf
:
ServerName example.com.conf
DocumentRoot /var/www/something
# Any other config you want to apply to both vhosts
還有你的虛擬主機檔案:
<VirtualHost *:443>
SSLEngine on
# Other SSL directives
Include /etc/path/to/config/example.com.conf
</VirtualHost>
<VirtualHost *:80>
Include /etc/path/to/config/example.com.conf
</VirtualHost>
答案4
查看 ApacheIf
結構並操作請求。看If
s的核心文檔和在其中使用的可用表達式列表。你可以這樣做:
<If "%{SERVER_PORT} == '443'">
# Do stuff
</If>
關於你的VirtualHost
標籤,我在 Apache2 文件中沒有看到這樣的解決方案。看http://httpd.apache.org/docs/2.2/en/vhosts/examples.html#port並嘗試您的選擇:Apache2 對不同的 IP 使用類似的而不是不同的連接埠(http://httpd.apache.org/docs/2.2/en/vhosts/examples.html#intraextra)。
我仍然建議使用 2 個不同的虛擬主機,這樣更清晰。無論如何,您的文件中將需要兩個NameVirtualHost
和。Listen
apache2.conf
編輯
我沒有意識到這個解決方案實際上引發了錯誤,但讓我們回到概念本身......實際上收聽 80 或 443 沒有問題。如果不是為了…加密,Apache2 很樂意為此提供一個優雅的解決方案。 Apache2 是用 C 語言開發的,除了執行緒和分支之外,它還使用套接字。在 C 語言中,使用 SSL 需要初始化 OpenSSL 元件,並圍繞基本套接字進行一些工作以實現整個 SSL 事物。您正在尋找一個簡單的解決方案,但背後的整個機制很棘手...這就是為什麼您無法在基本虛擬主機中啟用 SSL 的原因:HTTP 和 HTTPs 是不同的組件,並且在 Apache2 方式中,恐怕有第一個和第二個之間沒有繼承的概念。