SSLRequireSSL
directive?close_notify
SSL alert?Here is an example where all requests received on port 80 are redirected to the SSL port. Replace www.example.com with the hostname of your server. The new VirtualHost container will automatically apply to any requests received on the specified port (80), and mod_rewrite will always redirect these requests to the https (SSL) equivalent.
<VirtualHost *:80> RewriteEngine on RewriteRule ^/(.*) https://www.example.com/$1 [R,L] </VirtualHost>
Important: If using HTTP authentication, make sure it is only configured for your SSL virtual host. If it also applies to your port 80 requests, the authentication challenge can pre-empt the rewrite, resulting in userids and passwords being sent over an unencrypted session.
It is also recommended that you configure your port 80 virtual host with a different document root etc. from your SSL virtual host. This is to be sure that even if your rewrite fails, sensitive information cannot be served from that virtual host over unencrypted sessions.
gsk7capicmd
can create certificates with 2048 bit keys
ikeyman
(and gsk7cmd/ikeycmd) can create certificates with 2048 bit keys
For IBM HTTP Server 6.1 and earlier, the option for creating a certificate request with a 2048 bit key is only available when ikeyman reports the proper GSKit version.
IHS only supports RSA key exchange and RSA authentication. Ciphers using any of DSA authentication, or Diffie-Hellman / Ephemeral Diffie-Hellman are not supported.
The Java key management utility, keytool, will create DSA certificates by default, see the JSSE FAQ for more info.
If a third-party security product (such as eTrust) restricts what root can do, consult the vendor of the security product if the GSKit installation fails.
One example of such an error:
pkgadd: ERROR: checkinstall script did not complete successfully
Installation of failed (internal error).
This cannot be easily accomplished because there is no support for telling the web browser to "try again with a client certificate." The following recipe is one way to simulate this behavior without using an additional virtual host, which would involve redirecting select URLs to the alternate virtual host.
SSLClientAuth optional
in your virtual host
RewriteEngine on RewriteCond %{ENV:SSL_CLIENT_CERTBODYLEN} ^$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule /secure/ /certrequired.html
/certrequired.html
in the
previous step) describing what your users need to do
get a certificate. Note that users would probably have to
close and reopen their web browser before they'd be able to
select a client certificate, which can only happen at the
beginning of a new handshake.
(See this question for why we exclude error documents from the rule.)
This technote describes the configuration requirements:
Why?
A TLS extension has been defined in RFC 3546 which allows selection of the virtual host during the handshake, avoiding this dependence on IP addresses. In the coming years we'll see browsers which are able to support this TLS extension, but it will be a very long time before an customers could rely on that because older browsers would be unable to participate.
Note: It is the IP address/port combination which must be unique. You could support multiple SSL-enabled virtual hosts on the same IP address if they differ in port number, but that would require that clients specify the port number in https URLs for all but one of the SSL-enabled virtual hosts. |
Specifying any SSLv3/TLSv1 ciphers as illustrated in the performance guide will disable support for the NULL/Plaintext ciphers, provided you don't explicitly enumerate the following ciphers:
SSL_RSA_WITH_NULL_SHA (30) SSL_RSA_WITH_NULL_MD5 (31) SSL_NULL_WITH_NULL_NULL (32)Note: The following releases disable NULL ciphers by default:
Use the SSLCipherSpec directive and configure support for only SSLv3 and TLSv1 ciphers, as in the following example:
# This first cipher spec is CPU-intensive. You may want to # comment it out, if the other forms of encryption are # sufficient. SSLCipherSpec SSL_RSA_WITH_3DES_EDE_CBC_SHA SSLCipherSpec SSL_RSA_WITH_RC4_128_SHA SSLCipherSpec SSL_RSA_WITH_RC4_128_MD5 SSLCipherSpec SSL_RSA_WITH_DES_CBC_SHA SSLCipherSpec TLS_RSA_EXPORT1024_WITH_RC4_56_SHA SSLCipherSpec TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA # If 40-bit encryption is sufficient, uncomment these last two. # SSLCipherSpec SSL_RSA_EXPORT_WITH_RC4_40_MD5 # SSLCipherSpec SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 # Note: While excluding all SSLv2 ciphers disables the SSLv2 protocol, # you cannot exclude TLS_* ciphers to disable the TLSv1 protocol.Note: The following releases support the
SSLProtocolDisable
directive to accomplish this more directly.
Furthermore, only SSLProtocolDisable
can be used to disable TLSv1 or SSLv3 independently of each-other,
SSLCipherSpec
cannot disable only one of TLSv1 and SSLv3.
Place these directives inside the <VirtualHost > containers
which contain SSLEnable
. More Information
SSLVersion
allows access control to occur based on the SSL Protocol (SSLv2, SSLv3, TLSv1) the
client and server negotiated during the handshake, and can be used in a per-directory context (<Directory>,
<Location>).
SSLCipherBan
and SSLCipherRequire
operate in the same fashion as SSLVersion
,
but they look at the individual SSL cipher that was previously negotiated.
Unfortunately, the restrictions configured with SSLCipherBan
,
SSLCipherRequire
, and SSLVersion
do not influence the
actual SSL handshake and are only checked later on during request processing.
No SSL renegotiation is triggered by these directives, and instead the
configured 403 error response is issued at the application level. This 403
response may be difficult to distinguish from 403 errors triggered by other
authorization or access control directives.
As an example of why SSLVersion
is difficult to implement, if you use
SSLVersion SSLv3
(or SSLv2) and a browser connects with a
"stronger" protocol, not only do they get a generic 403 response but the user
would have to take some action to disable the stronger/preferred SSL
protocols in their browser to be able to reconnect. Using SSLVersion TLSv1
,
which requires the latest SSL protocol, sends clients without TLSv1 support a generic
403 response. This 403 response can be customized with the
ErrorDocument
directive but it is not distinguishable from other
access control errors in the same context.
Because of the limitations of SSLCipherBan, SSLCipherRequire, and SSLVersion, using mod_rewrite to analyze the SSL environment variables (HTTPS_CIPHER, SSL_PROTOCOL_VERSION, HTTPS_KEYSIZE) is much more flexible.
SSLCipherSpec
and
SSLProtocolDisable
influence the SSL handshake itself, and as a
consequence are only available in a per-vhost basis. While it's normally safe
to limit cipher support to "128-bit or
higher ciphers" or to disable SSLv2, we do not recommend restricting access
much further than this with SSLCipherSpec
and
SSLProtocolDisable
. Instead, use mod_rewrite as illustrated above
to enforce more restrictive access control; otherwise IHS and the browser may
not be able to negotiate a secure channel and users may not see a descriptive
error message from their browser.
This is an alternative to shutting out very old clients that might not be able to negotiate a strong cipher.
SSLCipherSpec
RewriteEngine On RewriteCond %{ENV:HTTPS_KEYSIZE} !^(128|168|256)$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule ^/secret3/ /128_or_higher.html
RewriteEngine On RewriteCond %{ENV:HTTPS_KEYSIZE} !^(128|168|256)$ [OR] RewriteCond %{ENV:SSL_PROTOCOL_VERSION} ^SSLV2$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule .* /low_grade_encryption.html
(See this question for why we exclude error documents from the rule.)
Instead of using mod_ibm_ssl SSLCipherSpec directives to allow only SSLv3 and TLSv1 ciphers, use mod_rewrite to recognize when SSLv2 is used, and redirect the request to a document explaining the restriction.
Example:
RewriteEngine On RewriteCond %{ENV:SSL_PROTOCOL_VERSION} ^SSLV2$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule .* /low_grade_encryption.html
RewriteEngine On RewriteCond %{ENV:HTTPS_CIPHER} !AES RewriteCond %{REQUEST_URI} !^/error/ RewriteRule ^/secret1/ /AES_only.html RewriteCond %{ENV:HTTPS_CIPHER} MD5 RewriteCond %{REQUEST_URI} !^/error/ RewriteRule ^/secret2/ /no_md5.html
(See this question for why we exclude error documents from the rule.)
SSLRequireSSL
directive?The SSLRequireSSL
directive is not supported with any
level of IHS. IHS uses a different SSL implementation than available
for Apache 1.3 or Apache 2.0.
Instead of using the SSLRequireSSL
directive to
specify that certain files or directories can only be served over SSL,
a customer can achieve the same result in different manner, by denying
access to the file or directory in the non-SSL configuration. In
following example, files under URI /onlyssl
can only be
served over SSL:
... # /onlyssl can't be served by default <Location /onlyssl> Order Allow,Deny Deny from all </Location> ... <VirtualHost *:443> SSLEnable ... # put this config for /onlyssl inside all SSL-enabled # VirtualHost containers <Location /onlyssl> Order Allow,Deny Allow from all </Location> </VirtualHost> ...
%{HTTPS_CIPHER}e
will log the name of the cipher
(e.g, TLS_RSA_WITH_AES_256_CBC_SHA
). Ensure that the
LogFormat directive which is changed is for the format used on the
CustomLog directive.
Example:
LogFormat "%h %l %u %t \"%r\" %>s %b %{HTTPS_CIPHER}e" common CustomLog logs/access_log common
9.48.108.152 - - [17/Feb/2005:15:37:39 -0500] "GET / HTTP/1.1" 200 1507 SSL_RSA_WITH_RC4_128_SHA 9.48.108.152 - - [17/Feb/2005:15:37:40 -0500] "GET /httpTech.view1.gif HTTP/1.1" 200 1814 SSL_RSA_WITH_RC4_128_SHA 9.48.108.152 - - [17/Feb/2005:15:37:40 -0500] "GET /httpTech.masthead.gif HTTP/1.1" 200 11844 SSL_RSA_WITH_RC4_128_SHA 9.48.108.152 - - [17/Feb/2005:15:37:41 -0500] "GET /httpTech.visit1.gif HTTP/1.1" 200 1457 SSL_RSA_WITH_RC4_128_SHA
For non-secure requests, "-" will be logged for the cipher specification.
The key size can be logged with the %{HTTPS_KEYSIZE}e
format string. See the section on SSL environment variables in the
IBM HTTP Server InfoCenter for information about other SSL environment
variables which can be logged. See the documentation for the
LogFormat and CustomLog directives for more information about format
strings in general.
A manual way to check this is to use Ethereal on the client system and start a packet trace capture. Then load the web page with your choice of web browser. Then stop the capture in Ethereal and look for the Server "Hello" response. This will appear in the packet window like this:
1.750088 server-ip-address client-ip-address TLS Server Hello, Certificate, [Unreassembled Packet]
Select that packet, then look for the "Handshake Protocol" information in the next window:
Handshake Protocol: Server Hello Handshake Type: Server Hello (2) Length: 70 Version: TLS 1.0 (0x0301) Random.gmt_unix_time: Apr 8, 2005 14:15:33.00000000 Random.bytes Session ID Length: 32 Session ID (32 bytes) Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004) Compression Method: null (0)
Check the display of the cipher suite.
Consult the Ethereal documentation for further information about using that tool.
If you have the openssl command-line client (not part of IHS, but distributed at www.openssl.org), that can display the cipher used as well, for an SSL session established by that command-line client.
To see which cipher is selected for the request, run openssl s_client -connect IPADDR:PORT and look for this part of the output:
New, TLSv1/SSLv3, Cipher is AES256-SHA
The symbolic names for the ciphers as displayed by openssl are are not the same symbolic names used by IHS. Here are the openssl names for common ciphers used with IHS:
IHS name | OpenSSL name |
TLS_RSA_WITH_AES_256_CBC_SHA | AES256-SHA |
TLS_RSA_WITH_AES_128_CBC_SHA | AES128-SHA |
SSL_RSA_WITH_RC4_128_SHA | RC4-SHA |
SSL_RSA_WITH_RC4_128_MD5 | RC4-MD5 |
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA | EXP1024-DES-CBC-SHA |
TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA | EXP1024-RC4-SHA |
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 | EXP-RC2-CBC-MD5 |
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 | EXP-RC2-CBC-MD5 |
SSL_RSA_EXPORT_WITH_RC4_40_MD5 | EXP-RC4-MD5 |
The openssl client supports many ciphers which are not supported by IHS.
openssl will hold the connection open until you interrupt it with the EOF character (usually <Ctrl>D on Unix systems).
You can restrict the openssl client to a particular cipher to see if IHS supports it, using the -cipher CIPHERNAME option.
Consult the OpenSSL documentation for further information about using the openssl command-line tool.
close_notify
SSL alert?IHS does not initiate a close_notify
alert during the
shutdown of a connection, but will respond to a client's
close_notify
with one of its own. This behavior is not
configurable.
In some non-keepalive cases, IHS cannot respond to a
close_notify
alert because IHS has already shutdown the
connection for writing, which will send a FIN to the client. In this
case, the client must react to the FIN instead of wait for a response
to the close_notify
.
Some non-browser clients (observed with an F5 load balancer) might
not close their end of the connection when the FIN is sent from IHS
but instead wait for a close_notify
alert. This can
cause an accumulation of sockets in FIN_WAIT_2 on the IHS
system. No response of any type can be sent after the FIN, so the
client should not wait for the close_notify
.
openssl s_client
command will wait for input (or Control-D). If the protocol
is disabled, openssl will report an exception similiar to the one reproduced below:
openssl s_client -connect ihshostname:443 -ssl2 openssl s_client -connect ihshostname:443 -ssl3 openssl s_client -connect ihshostname:443 -tls1
curl -vk -2 https://ihshostname curl -vk -3 https://ihshostname # -1 tests for TLSv1 curl -vk -1 https://ihshostnameFor more information see: How can I disable support for SSLv2?
Strong encryption (128-bit and above) is available when the "z/OS Security Level 3" unpriced optional feature has been installed. Without this feature, IHS is limited to the RSA ciphers listed in Table 1 of the System SSL Programming guide.
mod_ibm_ssl provides a set of access control directives that can be difficult to use (SSLClientAuthRequire, SSLClientAuthGroup). Instead, we recommend using mod_rewrite to inspect the SSL Client Certificate environment variables for access control.
The environment variables available for use in RewriteCond
directives are listed in the table
here. Note that many fields in the client certificate are optional and may be empty.
All example configurations should be placed inside a VirtualHost container with
<VirtualHost ...> SSLEnable SSLClientAuth required RewriteEngine on <VirtualHost>
RewriteCond %{ENV:SSL_CLIENT_O} !^IBM$ RewriteCond %{REQUEST_URI} !^/error/ # match any incoming URL RewriteRule ^ /IBM_org_required.html
RewriteCond %{ENV:SSL_CLIENT_O} !^IBM$ RewriteCond %{REQUEST_URI} !^/error/ # match URls beginning with /ibm_only RewriteRule ^/ibm_only /IBM_org_required.html
RewriteCond %{ENV:SSL_CLIENT_O} !^IBM$ RewriteCond %{REQUEST_URI} !^/error/ # Note: AND between RewriteCond's is implicit RewriteCond %{ENV:SSL_CLIENT_OU} ^Tivoli$ RewriteRule ^/secret/ /IBM_and_Tivoli_required.html
RewriteCond %{ENV:SSL_CLIENT_O} !^IBM$ [OR] RewriteCond %{ENV:SSL_CLIENT_OU} ^Tivoli$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule /secret/ /IBM_or_Tivoli_required.html
RewriteCond %{ENV:SSL_CLIENT_O} !^IBM$ [OR] RewriteCond %{ENV:SSL_CLIENT_OU} ^Tivoli$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule /secret/ - [F]
(See this question for why we exclude error documents from the rule.)
To identify the fields of interest in your users' certificates, a test environment can be used that logs client certificate details to the access log.
Note: This is 1 very long line followed by a shorter line.
If users have multiple client certificates, they will have to clear the SSL state of their browser to send a different certificate.
When comparing a non-empty pattern to an "unset" environment variable, mod_rewrite treats this as non-matching. This is different, but often preferable, behavior than SSLClientAuthRequire/SSLClientAuthGroup.
mod_rewrite directives must be specified in each Virtual Host for which you want them to take effect.
When SSLPKCSDriver
is specified, IHS/GSKit will not fallback to using software-based RSA crypto. For further confirmation, consult the list below.
Collect a GSKit trace that covers at least one SSL handshake. If the following command returns any text, the PKCS11 device was used for RSA operations.
strings /tmp/gsktrace_log | grep PKCS11KRYAlgorithmFactory::make_RSAPKCS_DecryptionAlgorithm
If you're using the integrated NCP crypto processors on a Sun Ultrasparc system you can run the following command after before and after an SSL handshake, and you should see the count increase:
kstat -n ncp0 -s rsaprivate
When you connect with a revoked certificate, the SSL handshake should be terminated by IHS before any page is delivered.
If LogLevel is set to warn, notice, info, or debug you will see the following messages in the error log when you connect with a revoked certificate:
[9fc7468] SSL0234W: SSL Handshake Failed, The certificate sent by the peer has expired or is invalid. [9fc7468] Certificate validation error during handshake, last PKIX/RFC3280 certificate validation error was GSKVAL_ERROR_REVOKED_CERT
gsk7capicmd
to generate
a certificate signing request using a SHA-2 algorithm (e.g. -sigalg sha512
).
During some recreates, IE8 is observed behaving like IE7. Like support for SNI, this may be a function of the OS as well, so IE8 on newer operating systems may inherit a smarter security library and be able to cope with the fragmentation.
One way to confirm that IHS is sending such a set of records is to look at the first write performed by the server with SSLTrace
configured.
SSL handshake initiated [x:3360 -> y:443] [20:52:35.000704700] SSL read begin bytes [5] timeout [300000000] SSL read end bytes [5] err [0] to [0] eof [0] ^ start of new SSL record SSL read begin bytes [65] timeout [300000000] SSL read end bytes [65] err [0] to [0] eof [0] ^ client hello SSL write begin bytes [16389] timeout [300000000] SSL write end bytes [16389] err [0] to [0] ^ maximum size of SSL record in first write of handshake SSL write begin bytes [485] timeout [300000000] SSL write end bytes [485] err [0] to [0] ^ immediate subsequent write for remainder
To circumvent the issue, delete expired personal or CA certificates from your KDB or use multiple key files instead of having many separate certificate chains in a single key file.
IHS only supports TLSv1.0, and negotiates TLSv1.1 and later handshakes down to TLSv1.0. GSKit 7.0.4.25 or later is required to successfully negotiate TLSv1.0 from a TLSV1.1 client.
The IHS TLSv1.0 support includes AES ciphers that were not yet standardized at the time TLSv1.0 was originally, but were defined in a later standalone specification and later incorporated into TLSv1.1.
No.
No.
No.
When the key size doubles, the CPU overhead of a full SSL handshake can increase by 8-12 times. Abbreviated (reused) handshakes are not affected by the change in key size.
As SSL handshakes (as opposed to block/bulk encryption or other processing overhead) can account for almost none, or almost all, of your overall CPU usage, it is critical to performance tests new certificates which contain larger keypairs under realistic workloads to determine the net change in CPU usage.
No, if the SSL handshake fails, there is no client-server connection that the server could use to send a custom error page response. The client browser is responsible for notifying the user of the error.
Triple DES comes in a 2-key and 3-key form, but the cipher as defined in SSL/TLS is always of the 3-key form (generally assesed at a strength of 112 bits, vs. 80 for 2-key).
If your server certificate includes Subject Alternate Names (SANs), they are part of the certificate and will be passed to SSL clients by any version of IHS. It is up to the client whether it recognizes the SANs and handles them properly, though most modern browsers will.
You can generate Certificate Signing Requests (CSRs) with SANs using gsk7cmd (command line) or the ikeyman graphical application. Note, though, that the Certificate Authority (CA) is not required to recognize the SAN in your CSR. If the CA ignores it, then the signed certificate will not include the SAN.
There is some one-time setup necessary in order to be sure you're using the latest tools and the SAN options are displayed.
The gsk7capicmd command-line tool in IHS v6.1 and v7 does not support Subject Alternate Names.
Some browsers seem to have a bug handling very long SSL server handshake messages.
The size of the server's SSL handshake message when requesting a client certificate depends on how many CA's it has. If it exceeds 16K, the SSL protocol requires it to be split into multiple SSL "records", which seems to confuse some browsers.
As of July 2010, here's how things look:
Complicating the issue at this time, Wireshark also seems to have a bug understanding these long messages, so looking at a packet trace in Wireshark might suggest that the message itself is incorrect. (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3303). However, GSKit support has carefully examined traces in this situation and verified that IHS and GSKit are sending the correct messages, according to the RFC.
Some possible remediations:
For more information, you can see this KB article: 933430 Clients cannot make connections if you require client certificates on a Web site or if you use IAS in Windows Server 2003, though the fix there only increases the limit to a single full SSL record, 16384 bytes. This blog entry from Jonathan Stephens describes the current problem as well.
If the server configuration is using mod_rewrite to test characteristics of SSL connections, be sure those rules aren't being applied to HTTP error documents. Here's what can happen:
The cause of the problem is that the internal SSL environment variables often tested in mod_rewrite rules are no longer available after the internal redirect to an HTTP error document. So a test like this fails:
RewriteCond %{ENV:SSL_CLIENT_O} !^Acme$ RewriteRule ^ /Acme_employees_only.html
The test is intended to redirect all non-Acme employees to a special page, but it does not find an SSL_CLIENT_O variable set to Acme after the internal redirect, so Acme employees who make a typo in a URL end up at a page telling them they're not Acme employees.
The solution is to not apply the mod_rewrite rules to error documents. If the error documents' URLs start with /error/, then the rules above could be fixed like this:
RewriteCond %{ENV:SSL_CLIENT_O} !^Acme$ RewriteCond %{REQUEST_URI} !^/error/ RewriteRule ^ /Acme_employees_only.html
Some Certificate Authorities (CAs) require that you create your Certificate Signing Request (CSR) with a particular signature algorithm and/or signature algorithm key size.
Supported algorithms
Ikeyman and Ikeycmd (gsk7md) v7 in IHS 6.0.2 and later support selecting between MD5 and SHA-1 by editing ikminit.properties. SHA-1 is the default in GSKit 7.0.4.27 and later.
Ikeyman and Ikeycmd (gsk7cmd) v8 in IHS 7.0 and later additionally support the SHA-2 family of ciphers directly via the UI (See documentation links below).
gsk7capicmd, the native command-line certificate management tool, supports the SHA-2 family of algorithms in 7.0.4.28 and later, regardless of the IHS release.
Here is the iKeyman doc (pdf) for the iKeyman (v8) available in IHS v7 and later. Page 48 documents the signature algorithm options for the command line. If you use the iKeyman graphical interface, some of the algorithm names might be displayed in an abbreviated form, but you can find the full names in the list on that page.
Here is the iKeyman doc (.pdf) for the iKeyman (v7) available in IHS v6.1 (with JDK v5). Make sure you remove the gskikm.jar file first so you're using the latest ikeyman. Page 44 documents the signature algorithm options for the command line. Version 7 of iKeyman does not make these options available in the graphical interface, but the signature algorithm can be chosen by editing ikminit.properties.
Here is the
gsk7capicmd doc (.pdf) for the gsk7capicmd available in IHS 6.0.2, 6.1, and 7.0. Search for -sigalg
for the valid parameters
during the -certreq -create
operation (-sigalg <md5 | sha1 | sha224 | sha256 | sha384 | sha512>).
Be sure to confirm that gsk7capicmd -version
(or <ihs_root>/bin/gsk7capicmd -version) reports at least
version 7.0.3.27.