智者没有给出正确的答案,他提出了正确的问题。
- 克劳德·列维·斯特劳斯
诸如`` 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.key
httpd.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 2048
server.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.csr
https://www.foo.dom/
,请在此处输入“ www.foo.dom”。您可以使用来查看此CSR的详细信息$ openssl req -noout -text -in server.csr
$ openssl x509 -noout -text -in server.crt
server.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 2048
server.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_cert
server.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必须知道Host
HTTP标头字段。为此,必须读取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
,瞧,您获得了回溯。对于其他调试器,请查阅本地调试器手册。