[Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Richard Eggert
I'm having a problem getting Crypt::SSLeay to authenticate server certificates when running under mod_perl on a web server that has mod_ssl enabled.  I'm not sure if this is a bug with Crypt::SSLeay, mod_ssl, mod_perl, Net::SSLeay, or the underlying OpenSSL libraries, but I'm hoping someone here will at least be able to narrow down where the problem lies.  Additionally, I'm running under a fairly old Linux distribution (Red Hat AS 3.0) with Perl 5.8.0, Apache 2.0.40, mod_perl 1.99_07, and libssl 0.9.6, but given that I haven't seen this problem reported anywhere else, let alone reported as having been fixed, I'm fairly confident that it still applies to more recent software versions.
 
Here's an overview of what I'm trying to do:
 
I've written a component that runs on a Perl-based web portal system residing under mod_perl on an Apache web server configured with mod_ssl.  User authentication is handled by the Perl-based portal framework, and my component connects to a servlet on a Tomcat server residing on a separate machine.  Due to the sensitive nature of the data being handled, all connections (from the user to the web server and from the web server to Tomcat) are being done via HTTPS.  For security reasons, I need to validate the Tomcat server's certificate.  I'm using LWP::UserAgent in conjunction with Crypt::SSLeay, and my Perl component is setting the appropriate environment variable (HTTPS_CA_FILE and/or HTTPS_CA_DIR, I've tried both) as per the Crypt::SSLeay documentation.
 
As a test scenario, I configured Tomcat with a self-signed certificate, and my component is using a bogus CA bundle.  The expected behavior is that the connection to Tomcat should fail due to the mismatched certificates.
 
 
However, what actually happens is that all requests sent to Tomcat succeed without even so much as a warning about the invalid certificate.
 
In the process of trying to narrow down the cause of the problem, I tried a number of things.
 
I tried running the snippet of code handling the HTTPS request to Tomcat as a standalone script with the exact same (mismatched) certificates in place.  This resulted in the expected behavior (failure due to invalid server certificate).
 
I tried disabling mod_ssl and connecting to the web server via HTTP instead of HTTPS (while still using HTTPS for the connection to Tomcat).  This also resulted in the expected behavior.
 
I tried running the snippet of code as a standalone script that gets invoked (in backticks) by my mod_perl component.  This resulted in the expected behavior. 
 
It's only when mod_ssl is enabled that my component behaves incorrectly and fails to properly validate the server's certificate against the CA bundle.
 
 
My best guess at what's happening is that mod_ssl is preloading libssl and configuring it according to its own requirements (and mod_ssl doesn't care about the certificates of other servers), and when my code runs (later) under mod_perl, the variables I'm sending it are being completely ignored.
 
 
Can this be fixed, or can anyone think of any viable workarounds for this (that don't involve running my code as a standalone script)?
 
 
Thanks.
 
Reply | Threaded
Open this post in threaded view
|

Re: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Marko Asplund
Richard Eggert wrote:
 > ...
> My best guess at what's happening is that mod_ssl is preloading libssl
> and configuring it according to its own requirements (and mod_ssl
> doesn't care about the certificates of other servers), and when my code
> runs (later) under mod_perl, the variables I'm sending it are being
> completely ignored.

Apache/mod_ssl server configuration should not interfere with your
libwww-perl/OpenSSL client configuration in any way.

try to do some printf debugging and print the relevant environment
variable values to a log file. do the variables have the correct values
when the script is being run?


br. aspa
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Richard Eggert
Yep.  Environment variables are being set.  I've even tried including a SetEnv in the Apache config instead of setting the variables inside my code.  I've written them to the log, and they're definitely being set.  They're just being ignored.  As I said before, the problem goes away if I just disable mod_ssl and connect to the server using regular HTTP (while continuing to use HTTPS to connect to Tomcat within my code).  mod_ssl on => HTTPS_CA_FILE ignored (or the code that's executed by whatever reads the variable fails for some reason).  mod_ssl off => HTTPS_CA_FILE gets used to validate Tomcat's certificate.   I can only assume that some global variable is being set when mod_ssl is configured that causes the change to HTTPS_CA_FILE (or HTTPS_CA_DIR) to be ignored when they're used by code running within mod_perl.  Two of us worked on it for hours and that's the only conclusion we could draw, though neither of would have thought that was the case before we saw it for ourselves.
 
 
 
Rich Eggert
Member of Technical Staff
Proteus Technologies, LLC
http://www.proteus-technologies.com
 
 
 
 

________________________________

From: [hidden email] on behalf of Marko Asplund
Sent: Mon 2/13/2006 2:13 PM
To: [hidden email]
Subject: Re: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?



Richard Eggert wrote:
 > ...
> My best guess at what's happening is that mod_ssl is preloading libssl
> and configuring it according to its own requirements (and mod_ssl
> doesn't care about the certificates of other servers), and when my code
> runs (later) under mod_perl, the variables I'm sending it are being
> completely ignored.

Apache/mod_ssl server configuration should not interfere with your
libwww-perl/OpenSSL client configuration in any way.

try to do some printf debugging and print the relevant environment
variable values to a log file. do the variables have the correct values
when the script is being run?


br. aspa
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]


 

winmail.dat (8K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Richard Eggert
In reply to this post by Marko Asplund
I've been digging through the code of the libraries for LWP, etc., and discovered that Net::HTTPS contains the following code:
 
if ($IO::Socket::SSL::VERSION){
     $SSL_SOCKET_CLASS = "IO::Socket::SSL"; # it was already loaded
}
else {
     eval { require Net::SSL; };  # from Crypt-SSLeay
     if ($@) {
          my $olderrsv = $@;
          eval {
               require IO::Socket::SSL;
          };
          if ($@) {
               $old_errsv =~ s/\s\(\@INC contains:.*\)/)/g;
               die $old_errsv . $@;
          }
          $SSL_SOCKET_CLASS = "IO::Socket::SSL";
     }
     else {
          $SSL_SOCKET_CLASS = "Net::SSL";
     }
}
 
 
 
It seems that it first tries to load the SSL module from Crypt::SSLeay first, and if that fails, it then tries to load IO::Socket::SSL, which, as far as I can tell, doesn't use HTTPS_CA_FILE (but may provide another mechanism for accomplishing the same thing).  Could it be that perhaps loading mod_ssl is causing the load of Net::SSL to fail (symbol conflict?), resulting in it falling back to IO::Socket::SSL (which ignores HTTPS_CA_FILE)?
 
Does IO::Socket::SSL provide a means for passing parameters via LWP::UserAgent (maybe through UserAgent's constructor or one of its other methods?)?  It definitely seems to support verification of peer certificates in its interface, but it's unclear from the available documentation how one does that in conjunction with LWP::UserAgent, if that's even possible.  If there is a way to do this, then an easy workaround seems to be to simply accomodate both configuration methods in my code.
 
 
 
 
 
Rich Eggert
Member of Technical Staff
Proteus Technologies, LLC
http://www.proteus-technologies.com
 

________________________________

From: [hidden email] on behalf of Marko Asplund
Sent: Mon 2/13/2006 2:13 PM
To: [hidden email]
Subject: Re: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?



Richard Eggert wrote:
 > ...
> My best guess at what's happening is that mod_ssl is preloading libssl
> and configuring it according to its own requirements (and mod_ssl
> doesn't care about the certificates of other servers), and when my code
> runs (later) under mod_perl, the variables I'm sending it are being
> completely ignored.

Apache/mod_ssl server configuration should not interfere with your
libwww-perl/OpenSSL client configuration in any way.

try to do some printf debugging and print the relevant environment
variable values to a log file. do the variables have the correct values
when the script is being run?


br. aspa
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]



winmail.dat (11K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Marko Asplund

On 2006-02-13, at 23.42, Richard Eggert wrote:

> It seems that it first tries to load the SSL module from  
> Crypt::SSLeay first, and if that fails, it then tries to load  
> IO::Socket::SSL, which, as far as I can tell, doesn't use  
> HTTPS_CA_FILE (but may provide another mechanism for accomplishing  
> the same thing).  Could it be that perhaps loading mod_ssl is  
> causing the load of Net::SSL to fail (symbol conflict?), resulting  
> in it falling back to IO::Socket::SSL (which ignores HTTPS_CA_FILE)?

do you have both IO::Socket::SSL (+Net::SSLeay) and Crypt::SSLeay  
properly installed on the system?

> Does IO::Socket::SSL provide a means for passing parameters via  
> LWP::UserAgent (maybe through UserAgent's constructor or one of its  
> other methods?)?
> It definitely seems to support verification of peer certificates in  
> its interface, but it's unclear from the available documentation  
> how one does that in conjunction with LWP::UserAgent, if that's  
> even possible.  If there is a way to do this, then an easy  
> workaround seems to be to simply accomodate both configuration  
> methods in my code.

i just did some testing and with one caveat you can do it like this  
with IO::Socket:SSL and LWP:

# NB: only works with ciphers that support certificate verification  
e.g. with Apache/mod_ssl:
#       SSLCipherSuite RSA
# With some cipher suites server certificate may not be verified.
use strict;
use IO::Socket::SSL 0.97;
use LWP::UserAgent;

my $ctx = new IO::Socket::SSL::SSL_Context(
   SSL_verify_mode => 0x01,
   SSL_ca_file => 'certs/8086.pem',
);
IO::Socket::SSL::set_default_context($ctx);

my $ua = LWP::UserAgent->new();
my $rq = HTTP::Request->new(GET => 'https://foo.bar.int:8086/');
my $rt = $ua->request($rq);
print $rt->content();

1;


br. aspa
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

RE: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Richard Eggert
Thanks.  That worked perfectly (well, actually, it failed, but that's what I wanted to happen).  Is there any way for me to tell within my code which SSL has been loaded, or am I pretty much stuck having to both set the HTTPS_CA_FILE variable as well as set the IO::Socket::SSL's default context in all situations?
 
By the way, to answer your first question, they're both installed properly, as far as I can tell (they both came with the default Red Hat installation, I think).  The Crypt::SSLeay version seems to get invoked whenever mod_ssl is disabled (since setting HTTPS_CA_FILE actually works properly in those cases), and the IO::Socket::SSL version gets invoked whenever mod_ssl is enabled.
 
Thanks again!
 
 
Rich

________________________________

From: [hidden email] on behalf of Marko Asplund
Sent: Tue 2/14/2006 7:12 AM
To: [hidden email]
Subject: Re: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?




On 2006-02-13, at 23.42, Richard Eggert wrote:

> It seems that it first tries to load the SSL module from
> Crypt::SSLeay first, and if that fails, it then tries to load
> IO::Socket::SSL, which, as far as I can tell, doesn't use
> HTTPS_CA_FILE (but may provide another mechanism for accomplishing
> the same thing).  Could it be that perhaps loading mod_ssl is
> causing the load of Net::SSL to fail (symbol conflict?), resulting
> in it falling back to IO::Socket::SSL (which ignores HTTPS_CA_FILE)?

do you have both IO::Socket::SSL (+Net::SSLeay) and Crypt::SSLeay
properly installed on the system?

> Does IO::Socket::SSL provide a means for passing parameters via
> LWP::UserAgent (maybe through UserAgent's constructor or one of its
> other methods?)?
> It definitely seems to support verification of peer certificates in
> its interface, but it's unclear from the available documentation
> how one does that in conjunction with LWP::UserAgent, if that's
> even possible.  If there is a way to do this, then an easy
> workaround seems to be to simply accomodate both configuration
> methods in my code.

i just did some testing and with one caveat you can do it like this
with IO::Socket:SSL and LWP:

# NB: only works with ciphers that support certificate verification
e.g. with Apache/mod_ssl:
#       SSLCipherSuite RSA
# With some cipher suites server certificate may not be verified.
use strict;
use IO::Socket::SSL 0.97;
use LWP::UserAgent;

my $ctx = new IO::Socket::SSL::SSL_Context(
   SSL_verify_mode => 0x01,
   SSL_ca_file => 'certs/8086.pem',
);
IO::Socket::SSL::set_default_context($ctx);

my $ua = LWP::UserAgent->new();
my $rq = HTTP::Request->new(GET => 'https://foo.bar.int:8086/');
my $rt = $ua->request($rq);
print $rt->content();

1;


br. aspa
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]



winmail.dat (9K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [Crypt::SSLeay] mod_ssl overrides settings by mod_perl applications?

Marko Asplund

On 2006-02-14, at 16.44, Richard Eggert wrote:

> Thanks.  That worked perfectly (well, actually, it failed, but  
> that's what I wanted to happen).  Is there any way for me to tell  
> within my code which SSL has been loaded, or am I pretty much stuck  
> having to both set the HTTPS_CA_FILE variable as well as set the  
> IO::Socket::SSL's default context in all situations?

i would recommend that you decide which module you want to use and  
make your code only work with that module.

based on the code in libwww-perl Net/HTTPS.pm it looks like you could  
simply add a 'use IO::Socket::SSL;' line in your code to make LWP  
always use that module.

you can determine whether a module has been loaded by testing package  
variable values such as $IO::Socket::SSL::VERSION.

> By the way, to answer your first question, they're both installed  
> properly, as far as I can tell (they both came with the default Red  
> Hat installation, I think).  The Crypt::SSLeay version seems to get  
> invoked whenever mod_ssl is disabled (since setting HTTPS_CA_FILE  
> actually works properly in those cases), and the IO::Socket::SSL  
> version gets invoked whenever mod_ssl is enabled.

as noted above you can debug this by testing package variables for  
each module.


br. aspa
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]