Forum OpenACS Q&A: Again: SSL Support for OpenACS - configuration correct?

Hi,

Using AOLServer4 and nsOpenSSL v3 I'm not yet sure if our configuration
is correct. I already took some major changes corresponding to the following post:
https://openacs.org/forums/message-view?message_id=320064

Thanks to Steve Mannning for his help which brought our many steps further already.

SSL connection is now working properly on the corresponding port. But when I try to
connect (e.g.) to the APM (Package Manager) under the unsecure http-Port there is no
response from the server. How can that be?

Here is the description what we did before, containing following important steps:

1. Generated Certfiles
2. OpenSSL Section of our AOLserver v4 config file
3. Pound Config File
4. Pound Proxy Extension (changes in acs-tcl package)
    4.1 admin-procs.tcl: replaced method "proc_doc ad_restrict_to_https"
    4.2 utilities-procs.tcl: replaced method "ad_proc util_current_location"
    4.3 security-procs.tcl: replaced method "ad_proc -public -deprecated ad_secure_conn_p"

================================
       1. Generated Certfiles
================================

Generated a cetfile.pem and a keyfile.pem following
the Installation Guide of OpenACS (https://openacs.org/doc/current/install-ssl.html).

Copied /etc/ssl/certs/ca-cert.pem /www/openacs/oacs-5-1/etc/certs/ca.pem

============================================================
       2. OpenSSL Section of our AOLserver v4 config file
============================================================

ns_section "ns/server/${server}/module/nsopenssl"

ns_param ModuleDir ${serverroot}/etc/certs

# NSD-driven connections:
ns_param ServerPort $httpsport
ns_param ServerHostname $hostname
ns_param ServerAddress $address
ns_param ServerCertFile certfile.pem
ns_param ServerKeyFile keyfile.pem
ns_param ServerProtocols "SSLv2, SSLv3, TLSv1"
ns_param ServerCipherSuite "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
ns_param ServerSessionCache true
ns_param ServerSessionCacheID 1
ns_param ServerSessionCacheSize 512
ns_param ServerSessionCacheTimeout 300
ns_param ServerPeerVerify false
ns_param ServerPeerVerifyDepth 3
ns_param ServerCADir ca
ns_param ServerCAFile ca.pem
ns_param ServerTrace false

# For listening and accepting SSL connections via Tcl/C API:
ns_param SockServerCertFile certfile.pem
ns_param SockServerKeyFile keyfile.pem
ns_param SockServerProtocols "SSLv2, SSLv3, TLSv1"
ns_param SockServerCipherSuite "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
ns_param SockServerSessionCache true
ns_param SockServerSessionCacheID 2
ns_param SockServerSessionCacheSize 512
ns_param SockServerSessionCacheTimeout 300
ns_param SockServerPeerVerify false
ns_param SockServerPeerVerifyDepth 3
ns_param SockServerCADir internal_ca
ns_param SockServerCAFile internal_ca.pem
ns_param SockServerTrace false

# Outgoing SSL connections
ns_param SockClientCertFile certfile.pem
ns_param SockClientKeyFile keyfile.pem
ns_param SockClientProtocols "SSLv2, SSLv3, TLSv1"
ns_param SockClientCipherSuite "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
ns_param SockClientSessionCache true
ns_param SockClientSessionCacheID 3
ns_param SockClientSessionCacheSize 512
ns_param SockClientSessionCacheTimeout 300
ns_param SockClientPeerVerify false
ns_param SockServerPeerVerifyDepth 3
ns_param SockClientCADir ca
ns_param SockClientCAFile ca.pem
ns_param SockClientTrace false

#OpenSSL library support:
#ns_param RandomFile /some/file
ns_param SeedBytes 1024

==============================
       3. Pound Config File
==============================

## global options:

User root
Group users
#RootJail /chroot/pound

## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
ExtendedHTTP 0

WebDAV 1

## Logging: (goes to syslog by default)
## 0 no logging
## 1 normal
## 2 extended
## 3 Apache-style (common log format)
LogLevel 3

## check backend every X secs [default:30]
Alive 10

## use hardware-accelleration card supported by openssl(1):
#SSLEngine < hw >

## Remove the X-SSL-Request header from incoming connections
## to prevent hackers from spoofing it
HeadRemove "X-SSL-Request"

## Add an extra header to tell AOLserver that
## the external connection is secure
HTTPSHeaders 0 "X-SSL-Request: true"

## Rewrite the URL [default:]
RewriteRedirect 0
## war in der "Maduraconfig" auf 0

## Timeout for a Server response [default:0] 0 means infinite
Server 0

## Timeout for a Client response [default:10]
Client 10

## Check the URL for correctness [default:0]
CheckURL 0

######################################################################
## listen, redirect and ... to:

## redirect all requests on port 8888 ("ListenHTTP") to the local webserver see "UrlGroup" below):
ListenHTTPS ourIP,ourPORT ..ourPATH/both.pem

LogLevel 4
HeadRemove "X-Forwarded-For"
WebDAV 1

# Dynamic Content Servers
UrlGroup ".*"
BackEnd 134.155.48.128,9001,9
EndGroup

==================================
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4. Pound Proxy Extension
==================================

=========================================
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.1 acs-tcl/tcl/admin-procs.tcl
=========================================

File: acs-tcl/tcl/admin-procs.tcl:
We replaced the actual method "ad_restrict_to_https" as follows...

proc_doc ad_restrict_to_https {conn args why} {
Redirects user to HTTPS.

@author Allen Pulsifer (mailto:pulsifer@mediaone.net)
@creation-date 2 November 2000
} {

if { [ad_conn driver] == "nsssl" ||
[ad_conn driver] == "nsssle" ||
[ad_conn driver] == "nsopenssl" ||
[string equal "true" [ns_set get [ad_conn headers]
X-SSL-Request]] } {
return "filter_ok"
}

set http_port [ns_config -int "ns/server/[ns_info server]/module/nssock" Port 80]
if { [ns_config ns/server/[ns_info server]/modules nsssl] != "" } {
set ssl_port [ns_config -int "ns/server/[ns_info server]/module/nsssl" Port 443]
} elseif { [ns_config ns/server/[ns_info server]/modules nsopenssl] != "" } {
set ssl_port [ns_config -int "ns/server/[ns_info server]/module/nsopenssl" ServerPort 443]
} elseif { [ns_config ns/server/[ns_info server]/modules nsssle] != "" } {
set ssl_port [ns_config -int "ns/server/[ns_info server]/module/nsssle" Port 443]
}

set host [ns_set iget [ad_conn headers] "host"]
if { [regexp {^(.*?):(.*)$} $host match host port] == 0 || [string compare $port $http_port] == 0 } {
set url [ad_conn url]

# ArsDigita probably meant to pass along any form variables (I hope)...
set form [ns_getform]

if {$form != ""} {
set size [ns_set size $form]
set url_args [list]

for {set i 0} {$i < $size} {incr i} {
set key [ns_set key $form $i]
set val [ns_set value $form $i]
lappend url_args [ns_urlencode $key]=[ns_urlencode $val]
}

append url "?[join $url_args &]"
}

if { $ssl_port == 443 } {
set redir "https://$host$url";
} else {
set redir "https://$host:$ssl_port$url";
}
ad_returnredirect $redir
# continue here since in filter
} else {
ad_return_forbidden "Please use HTTPS" "Sorry, you must use HTTPS to access this page."
# continue here since in filter
}

return "filter_return"
}

=============================================
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2 acs-tcl/tcl/utilities-procs.tcl
=============================================

We replaced the method util_current_location with the following one...

#Pound proxy extension
ad_proc util_current_location {{}} {

Like ad_conn location - Returns the location string of the
current request in the form protocol://hostname[:port] but it
looks at the Host header, that is, takes into account the host
name the client used although it may be different from the host
name from the server configuration file. If the Host header is
missing or empty util_current_location falls back to ad_conn
location.

If the web server is behind a Proxy server handling the SSL
connections, then all the web server sees are HTTP requests.

In that case an additional header 'X-SSL-Request' indicates that
the proxy forwarded an SSL connection to the
server. Redirections should not switch protocols and thus the
HTTP protocol that the server is aware of should be replaced
with HTTPS.

} {
set host_from_header [ns_set iget [ad_conn headers] Host]

# Host_from_header now hopefully contains hostname[:port]

set location_from_config_file [ad_conn location]

if {[empty_string_p $host_from_header]} {

# Hmm, there is no Host header. This must be an old browser
# such as MSIE 3. All~ we can do is:

return $location_from_config_file

} else {

# Replace the hostname[:port] part of
# $location_from_config_file with $host_from_header:

regsub -nocase {(^[a-z]+://).*} $location_from_config_file \\1$host_from_header location_from_host_header

# Switch to a secure protocol if the server is behind a proxy
# handling the SSL connection. In that case all the server
# sees are HTTP connections.

if {[string equal [ns_set iget [ad_conn headers] X-SSL-Request] true]} {
regsub -nocase ^http: $location_from_host_header https: location_from_host_header
}
return $location_from_host_header
}
}

============================================
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.2 acs-tcl/tcl/security-procs.tcl
============================================

We replaced the method "ad_proc -public ad_secure_conn_p" with this one:

#Pound proxy extension
ad_proc -public ad_secure_conn_p {
} {
Returns true if the connection [ad_conn] is secure (HTTPS), or
false otherwise. Takes into account that the web server might be
behind a SSL proxy. If so, all connections from the SSL proxy to
the server use the HTTP protocol but HTTPS requests to the SSL
proxy have an additional header. These HTTPS requests can be
identified by the header 'X-SSL-Request' with value 'true'.
} {
return [expr [string match "https:*" [ad_conn location]] || [string equal "true" [ns_set get [ad_conn headers] X-SSL-Request]]]
}

===============
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END OF POST
===============

Sven Schmitt,

Are 2 different ssl ports running or is one port configured using 2 different methods?

The standard nsOpenSSL configuration does not use Pound. I believe Pound is used as a proxy to convert an HTTPS connection with a client/browser to an HTTP connection to the server (aolserver) --another way to provide ssl service.

Torben,

thank you for your interest in our problem.

In deed we got 2 ssl ports running. One that is provided by pound an another one where nsopenssl is listening. The nsopenssl port works well, but unfortunately one thing does not work at all: switching from standard http-Port (or from Pound-Port) to https (e.g. by clicking on APM when on standard- or Pound-Port).

Got any ideas why that could be?

Regards,
Sven

Sven

It an impressively complicated setup. Personally I'd try simplfying it down to just the one pair of http and https ports and see if you get any clues from that.

- Steve

I agree with Steve. Wouldn't it be less complicated to setup two ssl ports using nsopenssl, or maybe even one port to start with?

That symptom looks like something that happens when the aolserver ns_param hostname from the config.tcl does not match the server's fully qualified pathname (as determined by the OS, pound and/or reachable by the browser), or maybe the hostname/port supplied by OpenACS when redirecting.

Steve,
Torben,

maybe you are right and our setup is just too complicated. Anyway, we will keep on trying (or maybe start again) :)

Thank you for you help.

Regards,
Sven