智者没有给出正确的答案,他提出了正确的问题。
- 克劳德·列维·斯特劳斯
诸如`` mod_ssl: Child could not open
SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (System error follows)
[...] System: Permission denied (errno: 13)''之类的错误通常是由于对父目录的权限限制过严引起的。确保所有的父目录(在这里/opt,
/opt/apache和/opt/apache/logs)具有在X位设置,以最低的,其下Apache的孩子正在运行的UID(见User指令)。
加密软件需要不可预测的数据源才能正常工作。许多开源操作系统都提供了一个用于此目的的“随机设备”(通常称为
/dev/random)。在其他系统上,应用程序必须在生成密钥或执行公共密钥加密之前,使用适当的数据手动为OpenSSL伪随机数生成器(PRNG)植入种子。从0.9.5版开始,如果PRNG尚未以至少128位随机性作为种子,则需要随机性的OpenSSL函数将报告错误。
为防止此错误,mod_ssl必须为PRNG提供足够的熵以使其正常工作。这可以通过SSLRandomSeed
指令来完成。
SSL_XXX变量对我的CGI和SSI脚本不可用?是。HTTP和HTTPS使用不同的服务器端口(HTTP绑定到端口80,HTTPS绑定到端口443),因此它们之间没有直接冲突。您可以运行绑定到这些端口的两个单独的服务器实例,也可以使用Apache优雅的虚拟托管工具创建两个虚拟服务器,这两个虚拟服务器均由同一Apache实例提供服务-一个通过HTTP响应端口80上的请求,另一个通过对端口443上的请求的HTTPS。
您可以在任何端口上运行HTTPS,但是标准指定端口443,默认情况下,该端口是所有HTTPS兼容浏览器的外观。您可以通过在URL中指定浏览器来强制浏览器使用其他端口。例如,如果您的服务器设置为通过端口8080上的HTTPS提供页面,则可以在以下位置访问它们https://example.com:8080/
虽然您通常只使用
$ telnet localhost 80
GET / HTTP/1.0
对于通过HTTP进行Apache的简单测试,由于TCP和HTTP之间的SSL协议,对于HTTPS而言并不是那么容易。s_client但是,借助OpenSSL的命令,您可以通过HTTPS进行类似的检查:
$ openssl s_client -connect localhost:443 -state -debug
GET / HTTP/1.0
在实际的HTTP响应之前,您将收到有关SSL握手的详细信息。对于直接了解HTTP和HTTPS,可以执行GET和POST操作,可以使用代理,支持字节范围等的更通用的命令行客户端,您应该看看漂亮的 cURL工具。使用此方法,可以检查Apache是否通过HTTP和HTTPS正确响应了请求,如下所示:
$ curl http://localhost/
$ curl https://localhost/
当您尝试通过HTTP连接到HTTPS服务器(或虚拟服务器)时(例如,使用http://example.com/而不是
https://example.com),可能会发生这种情况。当尝试通过HTTPS连接到HTTP服务器时(例如,https://example.com/在不支持HTTPS或在非标准端口上支持HTTPS的服务器上使用),也会发生这种情况
。确保您要连接到支持SSL的(虚拟)服务器。
该错误可能是由于配置错误引起的。请确保您的Listen指令与您的指令匹配
<VirtualHost>
。如果所有其他方法均失败,请使用所提供的默认配置重新开始mod_ssl。
SSL_XXX变量对我的CGI和SSI脚本不可用?请确保已SSLOptions +StdEnvVars为CGI / SSI请求的上下文启用了`` ''。
通常,要在HTTP和HTTPS之间切换,必须使用完全限定的超链接(因为必须更改URL方案)。mod_rewrite但是,使用可以操纵相对超链接,以达到相同的效果。
RewriteEngine on
RewriteRule "^/(.*)_SSL$" "https://%{SERVER_NAME}/$1" [R,L]
RewriteRule "^/(.*)_NOSSL$" "http://%{SERVER_NAME}/$1" [R,L]
通过此重写规则集,您可以使用形式的超链接
<a href="document.html_SSL">在相对链接中切换到HTTPS。(用NOSSL替换SSL以切换到HTTP。)
RSA私钥文件是一个数字文件,可用于解密发送给您的消息。它具有一个公共组件,您可以通过您的证书文件分发该组件,从而使人们可以加密发送给您的邮件。
证书签名请求(CSR)是一个数字文件,其中包含您的公共密钥和名称。您将CSR发送给认证机构(CA),该机构将通过签名将其转换为真实的证书。
证书包含您的RSA公钥,您的姓名,CA的名称,并由CA进行数字签名。知道CA的浏览器可以验证该证书上的签名,从而获得您的RSA公钥。这样一来,他们就可以发送只有您才能解密的消息。
有关SSL协议的一般说明,请参见“ 简介”一章。
是。通常,使用mod_ssl内置启动Apache就像不使用
内置启动Apache一样。但是,如果您的SSL私钥文件上有密码短语,则会弹出一个启动对话框,要求您输入密码短语。
启动服务器时必须手动输入密码短语可能会出现问题-例如,从系统启动脚本启动服务器时。在这种情况下,您可以按照步骤 下面从您的私有密钥才能删除该密码。请记住,这样做会带来额外的安全风险-请谨慎操作!
PATH。server.key和
server.crt文件:$ openssl req -new -x509 -nodes -out server.crt
-keyout server.keyhttpd.conf
文件中按以下方式使用:
SSLCertificateFile "/path/to/this/server.crt" SSLCertificateKeyFile "/path/to/this/server.key"
server.key并没有任何密码。要将密码短语添加到密钥,您应该运行以下命令,并根据要求输入并验证密码短语。$ openssl rsa -des3 -in server.key -out
server.key.new
$ mv server.key.new server.key
server.key在安全的位置备份文件和输入的密码。
以下是分步说明:
PATH。
$ openssl genrsa -des3 -out server.key 2048server.key文件以及您在安全位置输入的密码。您可以使用以下命令查看此RSA私钥的详细信息:$ openssl rsa -noout -text -in server.key$ openssl rsa -in server.key -out server.key.unsecure$ openssl req -new -key server.key -out server.csrhttps://www.foo.dom/,请在此处输入“ www.foo.dom”。您可以使用来查看此CSR的详细信息$ openssl req -noout -text -in server.csr$ openssl x509 -noout -text -in server.crtserver.key和
server.crt。这些可以在您的httpd.conf文件中如下使用
:
SSLCertificateFile "/path/to/this/server.crt" SSLCertificateKeyFile "/path/to/this/server.key"
server.csr不再需要
该文件。
简短的答案是使用
OpenSSL提供的CA.sh或CA.pl脚本。除非您有充分的理由不这样做,否则应将其优先使用。如果不能,则可以如下创建自签名证书:
$ openssl genrsa -des3 -out server.key 2048server.key文件以及您在安全位置输入的密码。您可以使用以下命令查看此RSA私钥的详细信息:$ openssl rsa -noout -text -in server.key$ openssl rsa -in server.key -out server.key.unsecure$ openssl req -new -x509 -nodes -sha1 -days 365
-key server.key -out server.crt -extensions usr_certserver.crt文件。$ openssl x509 -noout -text -in server.crt您只需要使用旧密码来阅读它,然后指定新的密码就可以再次写它。您可以使用以下命令完成此操作:
$ openssl rsa -des3 -in server.key -out server.key.new
$ mv server.key.new server.key
第一次要求输入PEM密码时,应输入旧密码。之后,系统会再次要求您输入密码-这次,请使用新的密码。如果要求您验证密码,则需要再次输入新密码。
在启动和每次重新启动时都会弹出此对话框的原因是,出于安全原因,server.key文件中的RSA私钥以加密格式存储。需要密码来解密此文件,以便可以读取和解析该文件。删除密码短语会消除服务器的安全性-请谨慎操作!
$ cp server.key server.key.org$ openssl rsa -in server.key.org -out server.key$ chmod 400 server.key现在server.key包含密钥的未加密副本。如果将服务器指向此文件,它将不会提示您输入密码。但是,如果有人获得了此密钥,他们将可以在网络上模拟您。请确保对该文件的权限使得只有root或Web服务器用户才能读取它(最好让您的Web服务器以root身份启动但以另一个用户身份运行,并且密钥只能由root读取)。
作为替代方法,您可以使用`` SSLPassPhraseDialog
exec:/path/to/program''功能。请记住,这当然既不安全也不安全。
私钥包含一系列数字。这些数字中的两个构成“公钥”,其他两个则属于“私钥”。生成CSR时会包含“公钥”位,这些位随后成为关联证书的一部分。
要检查证书中的公钥是否与私钥的公共部分匹配,您只需要比较这些数字即可。要查看证书和密钥,请运行以下命令:
$ openssl x509 -noout -text -in server.crt
$ openssl rsa -noout -text -in server.key
密钥和证书中的“模数”和“公共指数”部分必须匹配。由于公共指数通常为65537,并且很难直观地检查长模数是否相同,因此可以使用以下方法:
$ openssl x509 -noout -modulus -in server.crt | openssl md5
$ openssl rsa -noout -modulus -in server.key | openssl md5
剩下两个比较短的数字进行比较。从理论上讲,这些数字可能是相同的,而模数却不相同,但是这种可能性非常小。
如果您希望检查特定CSR属于哪个密钥或证书,可以对CSR执行相同的计算,如下所示:
$ openssl req -noout -modulus -in server.csr | openssl md5
OpenSSL的默认证书格式是PEM,它是Base64编码的DER,带有页眉和页脚行。对于某些应用程序(例如Microsoft Internet Explorer),您需要纯DER格式的证书。您可以使用以下命令将PEM文件cert.pem转换为相应的DER文件cert.der:
$ openssl x509 -in cert.pem -out cert.der -outform DER
发生这种情况的原因之一是因为您的服务器证书是由中间CA签名的。各种CA,例如Verisign或Thawte,已经开始不使用根证书而是使用中间证书来签署证书。
中间CA证书位于根CA证书(已安装在浏览器中)和服务器证书(已安装在服务器上)之间。为了使浏览器能够遍历并验证从服务器证书到根证书的信任链,需要为其提供中间证书。CA应该能够为您提供可以安装在服务器上的中间证书包。
您需要在SSLCertificateChainFile
指令中包括那些中间证书
。
造成这种情况的原因可能有多种,但主要的原因是该SSLSessionCache指令指定的SSL会话缓存存在问题
。DBM会话高速缓存是最有可能导致此问题的原因,因此使用SHM会话高速缓存(或完全不使用高速缓存)可能会有所帮助。
SSL使用强大的加密加密,因此需要进行大量的数字运算。当您通过HTTPS请求网页时,所有内容(甚至图像)在传输之前都已加密。因此,HTTPS流量增加导致负载增加。
这通常是由于/dev/random设备
SSLRandomSeed阻塞了read(2)调用,直到有足够的熵来满足请求所致。有关该SSLRandomSeed
指令的更多信息,请参见参考手册。
通常,所使用的OpenSSL版本所支持的任何SSL密码也受所支持mod_ssl。可用的密码取决于您构建OpenSSL的方式。通常,至少支持以下密码:
要确定可用密码的实际列表,应运行以下命令:
$ openssl ciphers -v
默认情况下,OpenSSL的也不会允许ADH密码,出于安全原因。如果选择启用这些密码,请确保您已意识到潜在的副作用。
为了使用匿名Diffie-Hellman(ADH)密码,必须使用`` -DSSL_ALLOW_ADH'' 构建OpenSSL ,然后将`` ADH'' 添加到您的SSLCipherSuite。
您在SSLCipherSuite
指令中犯了一个错误
(与中的预配置示例进行比较
extra/httpd-ssl.conf),或者在生成私钥并忽略或忽略了警告时选择使用DSA / DH算法而不是RSA。如果选择了DSA / DH,则服务器将无法使用基于RSA的SSL密码进行通信(至少在配置其他基于RSA的证书/密钥对之前)。像NS或IE这样的现代浏览器只能使用RSA密码通过SSL进行通信。结果是“没有共享密码”错误。要解决此问题,请使用RSA算法重新生成服务器证书/密钥对。
原因是非常技术性的,还有一个“鸡和鸡蛋”的问题。SSL协议层位于HTTP协议层之下,并封装HTTP。建立SSL连接(HTTPS)后,Apache / mod_ssl必须与客户端协商SSL协议参数。为此,mod_ssl必须咨询虚拟服务器的配置(例如,它必须寻找密码套件,服务器证书等)。但是为了转到正确的虚拟服务器,Apache必须知道HostHTTP标头字段。为此,必须读取HTTP请求标头。无法在SSL握手完成之前完成此操作,但是需要信息才能完成SSL握手阶段。请参阅下一个问题,以了解如何规避此问题。
请注意,如果您具有通配符SSL证书,或者使用subjectAltName字段在其上具有多个主机名的证书,则可以在基于名称的虚拟主机上使用SSL,而无需其他解决方法。
基于名称的虚拟主机是一种识别不同虚拟主机的非常流行的方法。它允许您将相同的IP地址和相同的端口号用于许多不同的站点。当人们继续使用SSL时,很自然地假设可以使用同一方法在同一服务器上具有许多不同的SSL虚拟主机。
这是可能的,但仅当使用使用0.9.8j或更高版本的OpenSSL构建的2.2.12或更高版本的Web服务器时才可行。这是因为它要求仅添加SSL规范的最新修订(即服务器名称指示(SNI))的功能。
请注意,如果您具有通配符SSL证书,或者使用subjectAltName字段在其上具有多个主机名的证书,则可以在基于名称的虚拟主机上使用SSL,而无需其他解决方法。
原因是SSL协议是封装HTTP协议的单独层。因此,SSL会话是一个单独的事务,发生在HTTP会话开始之前。服务器在IP地址X和端口Y(通常为443)上收到SSL请求。由于SSL请求不包含任何Host:字段,因此服务器无法决定要使用哪个SSL虚拟主机。通常,它只使用找到的第一个与指定的端口和IP地址匹配的地址。
但是,如果您使用的Web服务器和OpenSSL支持SNI,并且客户端的浏览器也支持SNI,则主机名将包含在原始SSL请求中,并且Web服务器可以选择正确的SSL虚拟主机。
当然,您可以使用基于名称的虚拟主机来识别许多非SSL虚拟主机(例如,全部在端口80上),然后拥有一个SSL虚拟主机(在端口443上)。但是,如果这样做,则必须确保将非SSL端口号放在NameVirtualHost指令上,例如
NameVirtualHost 192.168.1.1:80
其他解决方法包括:
为不同的SSL主机使用单独的IP地址。对不同的SSL主机使用不同的端口号。
尽管SSL压缩协商是在SSLv2和TLS规范中定义的,但直到2004年5月,RFC 3749才将DEFLATE定义为可协商的标准压缩方法。
使用zlib选项编译时,默认情况下,OpenSSL 0.9.8开始支持此功能
。如果客户端和服务器均支持压缩,则将使用压缩。但是,大多数客户端仍然尝试最初与SSLv2 Hello连接。由于SSLv2在其握手过程中未包含一系列首选压缩算法,因此无法与这些客户端协商压缩。如果客户端禁用对SSLv2的支持,则可能会发送SSLv3或TLS Hello,具体取决于所使用的SSL库,并且可能会设置压缩。您可以通过记录%{SSL_COMPRESS_METHOD}x变量来验证客户端是否使用SSL压缩。
否,用户名/密码以加密方式传输。Netscape浏览器中的图标实际上并未与SSL / TLS层同步。仅当传输实际网页数据的第一部分时,它才会切换到锁定状态,这可能会使人们感到困惑。基本身份验证功能是HTTP层的一部分,它位于HTTPS的SSL / TLS层之上。在HTTPS中进行任何HTTP数据通信之前,SSL / TLS层已完成其握手阶段,并已切换为加密通信。因此,请勿对此图标感到困惑。
第一个原因是,某些MSIE版本中的SSL实现存在一些与HTTP保持活动功能有关的细微错误,并且套接字连接关闭时SSL关闭通知警报。此外,在某些MSIE版本中,SSL和HTTP / 1.1功能之间的交互存在问题。您可以通过强制Apache不使用HTTP / 1.1,保持活动连接或将SSL关闭通知消息发送给MSIE客户端来解决这些问题。可以通过在支持SSL的虚拟主机部分中使用以下指令来完成此操作:
SetEnvIf User-Agent "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
此外,某些MSIE版本在特定密码方面存在问题。不幸的是,这不可能实现特定于MSIE的解决方法,因为早在SSL握手阶段就需要密码。因此,特定于MSIE的
SetEnvIf解决方案无法解决这些问题。相反,您将不得不对全局参数进行更大幅度的调整。在您决定这样做之前,请确保您的客户确实有问题。如果没有,请不要进行这些更改-它们会影响您的所有客户端(MSIE或其他)。
TLS-SRP(RFC 5054中指定的TLS的安全远程密码密钥交换)可以补充或替换认证SSL连接的证书。要使用TLS-SRP,请将SSLSRPVerifierFile指令设置为
指向OpenSSL SRP验证程序文件。要创建验证程序文件,请使用以下
openssl工具:
openssl srp -srpvfile passwd.srpv -add username
创建此文件后,在SSL服务器配置中指定它:
SSLSRPVerifierFile /path/to/passwd.srpv
要强制客户端使用非证书的TLS-SRP密码套件,请使用以下指令:
SSLCipherSuite "!DSS:!aRSA:SRP"
从版本2.4.7开始,
mod_ssl将使用DH参数,其中包括长度超过1024位的质数。但是,Java 7和更早版本将其对DH素数大小的支持限制为最大1024位。
如果基于Java的客户端因诸如和java.lang.RuntimeException: Could not generate DH keypair和java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)和httpd日志tlsv1 alert internal error (SSL alert number 80)
(LogLevel info
或更高级别)之类的异常而
中止
,则可以使用SSLCipherSuite
(可能与结合使用SSLHonorCipherOrder)重新排列mod_ssl的密码列表
,或者可以将1024位素数用于自定义DH参数,它将始终优先于任何内置DH参数。
要生成自定义DH参数,请使用openssl dhparam 1024
命令。或者,您可以使用RFC 2409第6.2节中的以下标准1024位DH参数:
-----BEGIN DH PARAMETERS----- MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL /1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC -----END DH PARAMETERS-----
将自定义参数(包括“ BEGIN DH PARAMETERS”和“ END DH PARAMETERS”行)添加到使用SSLCertificateFile指令配置的第一个证书文件的末尾
。
以下信息资源可用。如有问题,请先在这里搜索。
以下按优先顺序列出了对mod_ssl的所有支持可能性。请按此顺序处理这些可能性 -不要只选择您喜欢的外观。
您应始终至少提供以下信息:
httpd -v。可以通过运行确定OpenSSL版本openssl version。或者,如果您安装了Lynx,则可以运行命令lynx -mime_header
http://localhost/ | grep Server以单步收集此信息。
configure您使用的命令行。
通常不会,至少不会,除非您提供有关Apache转储内核的代码位置的更多详细信息。为了帮助您,通常总是需要回溯(请参阅下一个问题)。没有这些信息,几乎不可能找到问题并帮助您解决问题。
以下是完成回溯所需完成的步骤:
OPTIM="-g -ggdb3"'' 构建Apache + mod_ssl 才能获得此功能。在其他平台上至少需要`` OPTIM="-g"''。
CoreDumpDirectory /tmp'' 的指令来确保可以写入core-dump文件。这应该导致一个/tmp/core或/tmp/httpd.core文件。如果您没有其中之一,请尝试在非根UID下运行服务器。出于安全原因(内存中可能保留有特权信息),许多现代内核不允许进程在完成内核之后setuid()(除非这样做exec())转储内核。如有必要,可以/path/to/httpd -X
手动运行以强制不进行Apache分叉。
gdb /path/to/httpd
/tmp/httpd.core或类似的命令。在GDB中,您要做的就是输入bt,瞧,您获得了回溯。对于其他调试器,请查阅本地调试器手册。