在 RedHat 5.4 上源碼編譯安裝 OpenSSL 1.0.1 並啟用 Apache 2.2.22 的 mod_ssl 時,頻繁遭遇 checking for SSL_CTX_new... no 錯誤導致配置失敗。本文記錄從卸載系統自帶 OpenSSL、編譯安裝新版、修正編鏈路徑、到一鍵解決符號缺失的完整實戰過程,附帶 HTTPS 虛擬主機配置範例。
checking for SSL_CTX_new... no
checking for ENGINE_init... no
configure: error: ... Error, SSL/TLS libraries were missing or unusable
雖然 --with-ssl=/usr/local/openssl 指定了路徑,且頭文件檢測通過,但鏈接階段找不到關鍵符號。
OpenSSL 1.0.0+ 引入了新的符號版本控制,編譯 Apache 時若未正確鏈接 libdl(動態載入庫),會導致 SSL_CTX_new 等符號解析失敗。這是 Apache 2.2.x 與新版 OpenSSL 結合的已知問題(參考 Apache Bugzilla #48880)。
rpm -qa | grep -E 'openssl|ssl' | xargs rpm -e --nodeps
# 確認無殘留
rpm -qa | grep -i ssl
cd /usr/local/src
wget https://www.openssl.org/source/openssl-1.0.1.tar.gz
tar xzf openssl-1.0.1.tar.gz
cd openssl-1.0.1
./config --prefix=/usr/local/openssl shared zlib-dynamic
make depend && make && make install
# 建立動態庫緩存
echo "/usr/local/openssl/lib" > /etc/ld.so.conf.d/openssl.conf
ldconfig -v
關鍵參數:shared 生成 .so 動態庫,zlib-dynamic 動態鏈接 zlib,避免符號衝突。
cd /usr/local/src
wget https://archive.apache.org/dist/httpd/httpd-2.2.22.tar.gz
tar xzf httpd-2.2.22.tar.gz
cd httpd-2.2.22
# 核心修正:預置鏈接器標誌,強制鏈接 libdl
export LDFLAGS="-ldl"
./configure \
--prefix=/usr/local/apache2 \
--enable-so \
--enable-rewrite \
--enable-ssl \
--with-ssl=/usr/local/openssl \
--with-included-apr \
--with-pcre=/usr/local/pcre # 若系統 pcre 過舊
make && make install
export LDFLAGS="-ldl" 讓 configure 生成的 Makefile 在鏈接 mod_ssl 時自動加入 -ldl,解決 SSL_CTX_new 等符號由 libdl 動態解析的問題。
/usr/local/apache2/bin/httpd -V
/usr/local/apache2/bin/httpd -M | grep ssl
# 應顯示 ssl_module (shared)
# /usr/local/apache2/conf/httpd.conf
# 取消註釋
Include conf/extra/httpd-ssl.conf
DocumentRoot "/var/www/html"
ServerName www.example.com:443
ServerAdmin admin@example.com
ErrorLog "/usr/local/apache2/logs/ssl_error_log"
TransferLog "/usr/local/apache2/logs/ssl_access_log"
SSLEngine on
SSLCertificateFile "/usr/local/apache2/conf/ssl/server.crt"
SSLCertificateKeyFile "/usr/local/apache2/conf/ssl/server.key"
# 若證書檔已包含私鑰,註釋掉 SSLCertificateKeyFile
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
SSLOptions +StdEnvVars
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog "/usr/local/apache2/logs/ssl_request_log" \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
mkdir -p /usr/local/apache2/conf/ssl
cd /usr/local/apache2/conf/ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key -out server.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Example/OU=IT/CN=www.example.com"
chmod 600 server.key
/usr/local/apache2/bin/apachectl start
curl -k https://localhost
# 或瀏覽器訪問 https://server_ip
/usr/local/<pkg>,避免污染系統路徑,便於版本管理與回滾。ldconfig 並驗證 ldd /usr/local/apache2/modules/mod_ssl.so 確認 OpenSSL 庫正確解析。export LDFLAGS="-ldl" 寫入編譯腳本或 ~/.bashrc,避免後續重編遺漏。掌握 LDFLAGS=-ldl 這一鍵破解,讓 OpenSSL 1.0.1+ 與 Apache 2.2.x 完美共舞,構建高性能、高安全的 HTTPS 服務不再是難題。