Forum OpenACS Development: Proposed corrections to OpenACS default nsopenssl configuration

I finally made time to go through the standard OpenACS config.tcl and incorporate the nsopenssl config section from my own config.tcl. This eliminates the logfile errors that occur during iniital bootstrapping of Aolserver when using the OpenACS provided config.tcl, that the comments in the current version warn about.

Because I use different locations for my logfiles, I have not posted the entire config.tcl but instead have posted the relevant sections below for comment.

In passing, I note that there is a duplicated conditional statement at the end of the current config.tcl which should be removed:

if {[ns_info version] >= 4.5} {
ns_limits set default -maxupload [ns_config ns/server/${server}/module/nssock maxinput]
}

Regards
Richard

} else {

    #--------------------------------------------------------------------------------------------------
    # OpenSSL for Aolserver 4
    #--------------------------------------------------------------------------------------------------
    #
    # Configuration for nsopenssl v3.x modified by Richard Hamilton on 10-26-2010
    # (email: mailto:richard.hamilton@webteamworks.com), based on example configuration from README in
    # source code directory of nsopenssl.
    #
    # Note 1: nsopenssl.so v3.x supports multiple contexts for ssl connections in Aolserver v4.5
    #         so that you can configure multiple ssl listeners for each virtual server. For example,
    #         for each virtual server, you might wish to have different listeners for users and
    #         admins, and a third context for outgoing ssl connections (the 'client' context).
    #
    #         However, in OpenACS the security::locations proc has the nsopenssl context hard-coded
    #         as 'users'. Therefore, for Openacs up to the current version (5.6.0 as at 102610)
    #         you must only configure one context and it must be called 'users'. For this reason
    #         the example naming convention (of the form 'vs1_user_ctx') has not been used since
    #         it would be meaningless until OpenACS instances read their SSL context using ns_config.
    #         This forum post refers: http://www.openacs.org/forums/message-view?message_id=2983032
    #
    # Note 2: If you do configure more than one listener, each MUST have its own dedicated SSL key.
    #         This makes sense since otherwise there would be no point in opening up another port.
    #
    # Note 3: Code has been added that checks for the presence of the required key and certfiles for
    #         the OpenACS default context 'users'. The nsopenssl module will not load unless
    #         'users_cert.pem', 'users_key.pem', and './ca/users_cacert.pem' exist.
    #
    #         The default location assumed for key and certificate files is :
    #             /usr/local/aolserver/servers/${server}/modules/nsopenssl
    #
    #
    #--------------------------------------------------------------------------------------------------

    set httpsport_users $httpsport ;# Multiple contexts cannot share ports.

    ns_section "ns/server/${server}/module/nsopenssl"
        ns_param RandomFile /proc/kcore
        ns_param SeedBytes 1024
        # ServerPort is required by procs in acs-tcl/tcl/security-procs.tcl to find the https port.
        ns_param ServerPort           $httpsport_users
        # setting maxinput higher than practical may leave the server vulnerable to resource DoS attacks
        # see http://www.panoptic.com/wiki/aolserver/166
        # must set maxinput for nsopenssl as well as nssock
        ns_param   maxinput           [expr {$max_file_upload_mb * 1024 * 1024}] ;# Maximum File Size for uploads in bytes

    ns_section "ns/server/${server}/module/nsopenssl/sslcontexts"
        ns_param users        "SSL context used for regular user access"
    #    ns_param admins       "SSL context used for administrator access - not supported by OpenACS"
    #    ns_param client       "SSL context used for outgoing script socket connections - not supported by OpenACS"

    ns_section "ns/server/${server}/module/nsopenssl/defaults"
        ns_param server               users ;# Hard-coded into openACS security::locations proc
    #    ns_param client               client

    ns_section "ns/server/${server}/module/nsopenssl/sslcontext/users"
        ns_param Role                  server
        ns_param ModuleDir             ${homedir}/servers/${server}/modules/nsopenssl
        ns_param CertFile              users_cert.pem
        ns_param KeyFile               users_key.pem
        ns_param CADir                 ca ;# Directory containing certificate of signing authority
        ns_param CAFile                ca/users_cacert.pem
        # for Protocols                "ALL" = "SSLv2, SSLv3, TLSv1"
        ns_param Protocols             "SSLv3, TLSv1"
        ns_param CipherSuite           "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
        ns_param PeerVerify            false
        ns_param PeerVerifyDepth       3
        ns_param Trace                 false


#    ns_section "ns/server/${server}/module/nsopenssl/sslcontext/admins"
    #    ns_param Role                  server
    #    ns_param ModuleDir             /path/to/dir
    #    ns_param CertFile              admins_cert.pem
    #    ns_param KeyFile               admins_key.pem
    #    ns_param CADir                 ca
    #    ns_param CAFile                ca/admins_cacert.pem
        # for Protocols                "ALL" = "SSLv2, SSLv3, TLSv1"
    #    ns_param Protocols             "SSLv3, TLSv1"
    #    ns_param CipherSuite           "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
    #    ns_param PeerVerify            false
    #    ns_param PeerVerifyDepth       3
    #    ns_param Trace                 false

#    ns_section "ns/server/${server}/module/nsopenssl/sslcontext/client"
    #    ns_param Role                  client
    #    ns_param ModuleDir             /path/to/dir
    #    ns_param CertFile              client_cert.pem
    #    ns_param KeyFile               client_key.pem
    #    ns_param CADir                 ca
    #    ns_param CAFile                ca/client_cacert.pem
        # for Protocols                "ALL" = "SSLv2, SSLv3, TLSv1"
    #    ns_param Protocols             "SSLv3, TLSv1"
    #    ns_param CipherSuite           "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
    #    ns_param PeerVerify            false
    #    ns_param PeerVerifyDepth       3
    #    ns_param Trace                 false

    # SSL drivers. It is possible to configure multiple driver connections within a single
    # virtual server, with each allocated to its own named SSL context.However this feature is
    # not supported by OpenACS. Each driver defines a port to listen on and an explicitly named
    # SSL context to associate with it.
    ns_section "ns/server/${server}/module/nsopenssl/ssldrivers"
        ns_param users         "Driver for regular user access"
    #    ns_param admins        "Driver for administrator access"
    #    ns_param client        "Driver for outgoing ssl connections"

    ns_section "ns/server/${server}/module/nsopenssl/ssldriver/users"
        ns_param sslcontext            users
        ns_param port                  $httpsport_users
        ns_param hostname              $hostname
        ns_param address               $address
        # following added per
        # http://www.mail-archive.com/aolserver@listserv.aol.com/msg07365.html
        # Maximum File Size for uploads:
        ns_param   maxinput           [expr {$max_file_upload_mb * 1024 * 1024}] ;# in bytes
        # Maximum request time
        ns_param   recvwait           [expr {$max_file_upload_min * 60}] ;# in minutes

#    ns_section "ns/server/${server}/module/nsopenssl/ssldriver/admins"
    #    ns_param sslcontext            admins
    #    ns_param port                  $httpsport_admins ;# Not set up in OpenACS config.tcl
    #    ns_param hostname              $hostname
    #    ns_param address               $address

#    ns_section "ns/server/${server}/module/nsopenssl/ssldriver/client"
    #    ns_param sslcontext            client
    #    ns_param port                  $httpsport_client ;# Not set up in OpenACS config.tcl
    #    ns_param hostname              $hostname
    #    ns_param address               $address
}
**Replace only appropriate lines in section that loads modules**

__________________________________________________________________


ns_section ns/server/${server}/modules
    ns_param   nssock             ${bindir}/nssock.so
    ns_param   nslog              ${bindir}/nslog.so
    ns_param   nssha1             ${bindir}/nssha1.so
    # since aolserver version 4.5.1 built-in ns_cache, so we dont
    # need to load the nscache module.
    if {[ns_info version] < 4.5 || [ns_info patchlevel] eq "4.5.0"} {
          ns_param   nscache            ${bindir}/nscache.so
    }
    # openacs versions earlier than 5.x requires nsxml
#    ns_param nsxml              ${bindir}/nsxml.so

    #---------------------------------------------------------------------
    # nsopenssl will fail unless the cert files are present as specified
    if { [file exists ${homedir}/servers/${server}/modules/nsopenssl/users_cert.pem]
        && [file exists ${homedir}/servers/${server}/modules/nsopenssl/users_key.pem]
        && [file exists ${homedir}/servers/${server}/modules/nsopenssl/ca/users_cacert.pem] } {
        ns_param   nsopenssl          ${bindir}/nsopenssl.so
    }

Richard,

What version of config.tcl are you working from?

cvs head doesn't seem to have the duplicate condition statement as far as I can tell: http://fisheye.openacs.org/browse/OpenACS/openacs-4/etc/config.tcl?r=HEAD

What are the logfile errors you were seeing that this proposal resolves?

Torben

Torben,

I am working from a recent HEAD checkout, and the errors I am referring to are those referred to in the comments at lines 399 to 401 of config.tcl.

I note that the duplicate conditional is not present in this file, and I suspect a slip of the paste finger at some point in my editor!!

The rest on my code should be fine as it has been taken from a working installation!

Can't get the staff!! 😉

R.

Hi Richard,

Hardcoding the pem files to that location won't work for OSes that place aolserver somewhere else in the file hierarchy (such as freebsd).

The server should be able to read the pem files of any os when they are located within $serverroot, which is why the config.tcl currently references them at ${serverroot}/etc/certs by default.

The files need to be accessible by the running aolserver, and so should be given the usual file permissions for that.

If for some reason, it's decided to make these changes to config.tcl, a moduleroot variable should be defined early in config.tcl for this use, since aolserver modules are placed in various locations in various OSes and distributions.

cheers,

Torben

Torben,

Thanks for the comments. I agree that this should be as you suggest. This code is lifted from my own installation and I keep the SSL files under the Aolserver tree. I should have changed this before posting because it isn't the crux of the change I propose.

The main thing is that we comment out all but the users context for OpenACS and put some explanation into the comments to capture the context issue which is otherwise not documented.

Regards
Richard

Hi Richard,

The context "admin" is basically there as a documented example, if one wants to have multiple contexts. It is commented out by default.

The client context is setup for outbound SSL connections. It's only activated if nsopenssl module is activated.

What messages do you see in the logfile that indicates there is a problem?

I'm all for documentation improvements. What is unclear? I can see how there should be a note in config.tcl nsopenssl/defaults section stating that a separate set of files must be used for each context.. What else?

Torben,

The reason I posted this was because of a conversation (can't find it in the forum - may have been on the openacs chat) with DaveB in which this came up. Dave's comments suggested that there was a problem with the default config.tcl file that led to ns_log errors being recorded.

I have always based my config on the README within the nsopenssl source directory and have had no error log entries. After you very kindly helped me to sort out the issue over the hard-coded 'users' context, it has been my intention to propose some alterations to config.tcl.

I have never needed a 'client' context and have not seem any code that uses it, however I can see that this may be useful in the case of, for example, payment processing gateways.

The only things that look 'not quite right' to me in the default config.tcl are:

1) Comments saying that this file will cause errors in the logfile but don't worry folks it works anyway!

2) The fact that the CADir and CAFile declarations are commented out. As I understand it, these are required to verify the chain of trust for the SSL key and cert files for the context and should be set. I suspect that this is the source of the logfile error. I have mine set and I see no errors in the ns_log output.

My intention really was just to eliminate any log errors, simplify and clarify by adding information to the comments.

This reply to Bart T from Scott G has useful reference material in it:

http://www.mail-archive.com/aolserver@listserv.aol.com/msg06022.html

I would be interested in working with someone to remove the hard-coded context from the OpenACS security procs so that OpenACS can work with the full flexibility of nsopenssl.

Please be assured that no criticism of anyone or anything was intended or implied by my posting.

Regards
Richard

Hi Richard,

No negative criticism was considered etc from here; I'm sorry if my message seemed that way. I'm earnestly trying to figure out what the problem is so we can fix it. I've been using nsopenssl since y2k, so I lack having a fresh look at it.

Similarly, the thread you reference is early nsopenssl 3.0 release from 2003. The issues seem to be dealt with already. The current config.tcl mirrors Scott Goodwin's example AFAICT. config.tcl also has ns_section "ns/server/${server}/module/nsopenssl/defaults"

I don't know that there's a simple way around removing the default contexts 'users' and 'client'. As I understand it, the full flexibility of nsopenssl is available as is. If one wants to define another context, define it by using the 'admin' context as an example.

There's some config.tcl files out there that show how to setup virtual servers using http, and some discussion of revising the OpenACS default config.tcl to use that format. I like the idea, especially if it adds flexibility to installations and doesn't just add more work.

OpenACS has host-node mapping for serving multiple domains from one aolserver instance (incompletely implemented). Using virtual servers may be a cleaner way of accomplishing this, but I believe would lack sharing of db pools between instances.

https has an added requirement that each domain requires a different certificate/key (unless you're using self-signed certificates and don't mind the browser messages). Since CA cert/keys are an added cost, usually an organization splits the deployment into separate aolserver instances per key (and IP), to avoid any issues of two or more keys sharing the same IP address (different subdomains and/or ports). Often a requirement of a purchased key is that it runs on it's own IP for security reasons.

So, how is OpenACS limited with these contexts? Removing hard-coded things can be a good idea, but how is OpenACS limited by these hard coded contexts? What is the full flexibility of nsopenssl that OpenACS is not leveraging?

cheers,

Torben

Torben,

You're probably right in suggesting that the use case is not strong. I do think that there is a potential use case for hosting multiple domains (any number of which using OpenACS) in a single Aolserver instance, with separate ssl contexts. In this case I would not want the database pools to be shared between separate domains for security reasons. However, this would of course be almost as resource intensive as completely separate servers because each OpenACS virtual server would have to load a full set of tcl libs into memory.

This arrangement would be better security wise than host-node mapping because it would enable the databases to be kept completely separate, and would enable you to set up a separate openssl context for each OpenACS domain.

Of course, as things stand already you can set up additional contexts for non-OpenACS domains hosted as virtual servers alongside an OpenACS in the same config.tcl, and NginX is also a great tool for serving up static files and reverse proxying, with its own support for openssl.

Host node mapping and Aolserver v4 virtual hosting both suffer from the problem that you can't bring a single server down when necessary, and you have to post-process the logfiles to separate entries for each domain for analysis.

I guess there is no need to change 'users', it just seems untidy as it is! 😉

I still think though that the template config.tcl should not cause ns_log errors or warnings, and if the current one doesn't then the comments shouldn't warn that it will!

I also think that the cacert file should be loaded even if you are using your own personal CA. As it stands this is commented out in the current release version of config.tcl

Regards
Richard

Hi Richard,

Okay, I think we can address your last two points. I find it's less problematic during installation to append the CAcert to the end of the CA issued cert, but that's not a good reason to not do this.

So, uncomment the CA.pem line, and add a comment that CA.pem can alternately be commented out and appended to certfile.pem. By CA.pem, I assume you are referring to the CAFile and CADir values in ns/server/${server}/module/nsopenssl/sslcontext/users. CA.pem is currently only found in the Aolserver 3.3 nsopenssl part of config.tcl.

There's another clean up point that should be addressed at the same time:

removing '+SSLv2:' from users context CipherSuite.

Anything else?

Hmm.. since aolserver 3.3 is not supported with the newer OpenACS[1], the 3.3 version should be removed.

We should also mention the possibility of using an alternate ssl via tcllib. I just need to find the reference...

1. https://openacs.org/xowiki/openacs-compatibility-matrix

Torben,

A couple of other points to go towards this process:

1) This morning I tried to run the installer using a config.tcl based on the one shipping with 5.6.0 only to find that the installer couldn't talk to the db (PostgreSQL). The driver had loaded fine and reported successfully opening the pools in the error log. No errors appeared in the ns_log output.

However as soon as the installer tried to talk to the db to write the data structures, it discovered that it couldn't find psql.

I fiddled around for a while checking the env for the server, and finding nothing amiss then set up nscp and started poking around. I traced the problem to db_get_pgbin and ran through the proc stepwise in the control port.

The upshot is that I reckon that whoever last edited the master version of config.tcl was an Oracle user!! 😉

Why?

Please see lines 526 to 530:

http://cvs.openacs.org/browse/OpenACS/openacs-4/etc/config.tcl?r=HEAD

See anything missing? 😊

2) Lines 399-401 are not helpful guidance. It was on the basis of the 'fixes welcome' that I started this thread. I think the default config.tcl for OpenACS ideally should not announce that it will throw errors and invite fixes.

3) Lines 476-481. Personally I am not happy with the 'might stabilise'. I think we should avoid including settings that differ from defaults without a positive and proven rationale. This does not sound confident enough to earn its place.

Regards
Richard

[response to (1)]

Speaking to what I think you said the original problem was (can't find psql), normally the pg bins are found by setting PATH and maybe also LD_LIBRARY_PATH for the call to nsd.

The committer of 1.41 was Gustaf, and it looks like in line 526 (as well as many other places in the file) he corrected the operator by making this:

if {$database == "oracle"} {

look like this instead:

if {$database eq "oracle"} {

which is the right thing to do as the intent is to compare strings but == is a numeric comparison. That's the only line (526) that had been changed in the range 526-530 since 1.40. It looks like in 1.41 Gustaf wanted to go thru the config file and correct a bunch of instances of the "wrong operator" problem.

By "what's missing" (in lines 526 - 530) you must mean an "else" clause for pg. If an else clause would be put in, what is needed there?

-Jim

Jim,

When I said whoever last edited it, I didn't mean literally 'the last person to touch it'! I hadn't checked who it was, and I certainly wasn't trying to blame Gustaf!! God forbid! 😊

What is needed there is:

if { $database eq "oracle } {
    blah blah blah
  } else {
    ns_section "ns/db/driver/postgres"
    ns_param    pgbin        /usr/local/pgsql/bin
}

I also had assumed that the path to psql was derived from the PATH environment variable for the user Aolserver was running as, but today I learned from my efforts that this is not in fact the case. On my installations, when I run 'nsd -it /path/to/config.tcl -u user -g group' from inittab, and then log into nscp and type 'env get path', the value for PATH in the nsd environment is not the same as the PATH value that the user sees in a tty.

Correct me if I am wrong, but I conclude therefore that Aolserver therefore doesn't source the user's environment when launched from inittab with '-u user'. This would be analogous to the case of 'su user' vs. 'su - user'.

Consequently, this config parameter would seem to be essential. Adding it solved the problem for me!

Regards
Richard

Heya Richard,

Hmm, inittab... didn't realize that was how you were starting it, but it seems it could work out the same:

#!/bin/bash

export PATH=/usr/local/pgsql/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/lib

# with these exports, you should be able to run nsd and
# it should pick up PATH and LD_LIBRARY_PATH as set above.

nsd -it /path/to/config.tcl -u user -g group
# or
exec nsd -it /path/to/config.tcl -u user -g group

# as far as I know, it was never needed to put the pg dirs
# in the config file as long as they properly got
# transmitted to the process. For example, take a look at
# $service/etc/daemontools/run

Jim,

On my distribution the PATH that the user switched Aolserver is passed is that niether of root nor the user to which it is switched.

I am sure that there probably is a way to do this with the environment variables, but why bother fiddling with that when a config entry specifically configures the server? In any case, if you want to configure a server to a specific version of PostgreSQL (i.e. also running an old ACS 4.6.3 site), this provides an elegant mechanism for doing it.

This config declaration certainly used to be in the config file and has been in my own config.tcl for over ten years.

Also, adding it completes the param structure and results in symmetry! 😉 Perhaps it is my obsessive nature, but why leave something out that has potential benefits just because it can be left out?

Regards
Richard

Heya Richard
I am sure that there probably is a way to do this with the environment variables,

Yes, there is definitely a way to do it with env vars, and I posted an example script in this thread which sets the env vars appropriately, and calls nsd with the example parameters you posted. There is another one floating around called nsd-postgres that feeds parameters fed to it to the nsd.

but why bother fiddling with that when a config entry specifically configures the server?

Because in at least the config file you show for your personal config, it's a hard wiring that IMO shouldn't appear in the config file.

Also in many postgres (and oracle too) installations, the dynamic libraries are not in the usual system-wide places in all dists, so setting a second environment variable, namely LD_LIBRARY_PATH is sometimes necessary. In the case of a postgres compiled in the default place (/usr/local/pgsql), this -is- the case and so setting the variable -is- necessary.

And so, why not set both vars, and leave out having to specify the pg bin and lib dirs in the config file.

One more clarification, it's perfectly OK for you to have your config file do anything you want; I didn't mean to imply otherwise, what I meant was that the default config supplied by openacs should be free of having to do that.

Jim,

On my distribution I do have to set LD_LIBRARY_PATH in order to compile postgres (plus a few other nasty obscure little steps!). However, I run each Aolserver as a different user for each site for security reasons.

This would require that I set the two env vars for every username running nsd on the system instead of just for user postgres. Not a big ask, but extra configuration nonetheless.

On my setup I simply duplicate the config file and adjust the service specific details.

There is also the possibility that someone new to this would struggle with the environment variables whilst being able to fill in the gaps in the config.tcl.

I don't feel strongly either way, I am just feeding back the things I found as I updated by own config.tcl to match the latest default.

Certainly, anything we can do to remove obstacles to people getting it all running can only be good.

Thanks for the replies.

Regards
Richard

Yeah, Richard, I believe your point 1 is a distribution issue. Distributions solve this differently and locate the pg directory in different places..
Richard,

Good point regarding your point 2. That was for early implementations (Jan 2005), before the configuration stabilized.

Regarding point 3, setting these parameters added stability for implementations I managed. I also have tremendous respect for Bart's competence with nsopenssl configurations. He was an early adopter of nsopenssl with OpenACS. I lack the expertise to challenge this configuration; and believe he had legitimate reasons for including these settings in his commercial deployments. I can surmise that these cache settings help SSL connections scale well, much like other cache settings within OpenACS help with scalability. Many settings in config.tcl differ from AOLserver defaults. Since you don't feel the language is confident enough, I can change it by removing the casual testimonial.

Anything else?

Am also going to add comments about connecting to other databases. This addition is based on info from this thread: https://openacs.org/forums/message-view?message_id=213006
cheers,
Torben