You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Tim Bishop <ti...@activespace.com> on 2000/08/03 23:09:28 UTC

[Mason]Re: how to check for ssl.


On Thu, 3 Aug 2000, Stas Bekman wrote:

> On Thu, 3 Aug 2000, ___cliff rayman___ wrote:
> 
> > use Apache::URI ();
> > $r->parsed_uri->scheme;
> > 
> > returns http or https
> 
> Not really, you can spoof both:
> http://thingy.kcilink.com/modperlguide/config/Knowing_the_proxy_pass_ed_Connec.html
>  
> > scotta@musiciansfriend.com wrote:
> > 
> > > I've got a section of our site where I want to force the user to
> > > connect via ssl.
> > > Inside of mod_perl, is there a parameter I can grab to see whether
> > > the connection is ssl or not?  Or a way to get the port number?
> > >
> > > Scott

I had the same problem recently, where the mod_perl backend server did not
know what was happening on the front end with respect to SSL.  I solved it
in a way that is flexible, but perhaps overkill:

I patched mod_headers.c on the frontend server to allow one to attach
extra headers to requests when they are proxied to the backend.  This
allows you to stuff info in headers about SSL, or the remote-ip, etc.  
You can specify headers to set with the same substitution syntax as
RewriteRule

(The patch is attached)

example:

On the front-end server:
( cd apache_1.3.12 ; patch -p1 <ProxyHeaderRewrite.p2.patch ;make install)

in httpd.conf;
# tell upstream server the ip of the request, and pass along the Host
ProxyHeaderRewrite append X-Forwarded-For      "%{REMOTE_ADDR}" 
ProxyHeaderRewrite append X-Frontend-Host      "%{HTTP_HOST}"
# tell upstream server info on SSL status
<VirtualHost _default_:443>
    SSLOptions StdEnvVars
    ProxyHeaderRewrite append X-SSL-Cipher "%{ENV:SSL_PROTOCOL} ${ENV:SSL_CIPHER}"
</VirtualHost>
# tell upstream server the virtual host used
ProxyHeaderRewrite append X-Frontend-Host "%{HTTP:Host}"



Now, for a typical SSL request that is proxied to the back end (as
plaintext), these headers are added: 
X-Forwarded-For: 1.2.3.4
X-Frontend-Host: my.frontend.site.com
X-SSL-Cipher: SSLv3 IDEA



On the backend server, parse the headers with some little perl handler in
startup.pl, and stuff the info where most other modules expect it (in $r,
or in environment vars):

sub My::ProxyHeaderParse ($) {
   my $r = shift;

      # we'll only look at the X-Forwarded-For header if the requests
      # comes from our local network
      return OK unless ($r->connection->remote_ip =~ /^192\.168/ );

      if (my ($ip) = $r->header_in('X-Forwarded-For') =~ /([^,\s]+)$/) {
          $r->connection->remote_ip($ip);
      }

      # mv X-Frontend-Host: into Host: header
      my $host_header = $r->header_in('X-Frontend-Host');
      if ( defined($host_header) ) {
          $r->header_in('Host', $host_header)
      }

      # set up ssl env vars, if present in a X-SSL-Cipher header
      my $ssl_header = $r->header_in('X-SSL-Cipher');
      if ( defined($ssl_header) ) {
          ($ENV{SSL_PROTOCOL}, $ENV{SSL_CIPHER}) = split(/ /,$ssl_header);
          $ENV{HTTPS} = 'ON';  # CGI.pm:protocol() require 'ON'  (not 1 !)
      } 
        
   return OK;
  }

# called in httpd.conf
#  PerlPostReadRequestHandler My::ProxyHeaderParse