EZproxy includes a management web site that allows for normal day-to-day operational tasks to be carried out with just a few clicks. Need to setup SSL? No problem! Need to review access logs? They're right there. Test network connectivity? Click, click, done. You can even test out new authentication settings prior to adding them to the configuration file.
There are a few areas where the interface falls short, though.
One area is with session handling. We were working with session lifetimes, trying to find a good balance between having the patron re-authenticate and their proxy session lifetime. That was when we discovered a bug where EZproxy resets the session timers for all sessions every time it is restarted. Since we were changing the session lifetime values, we were restarting the proxy server more frequently than normal, and soon wound up with thousands of sessions that were considered active.
The admin interface to EZproxy would have you go to server status, click on each session, and click Terminate Session. That's OK for a handful of sessions, but when you have hundreds of incoming sessions, trying to clean out stale sessions to keep the service up is like trying to drink from a fire hose. I eventually wound up writing a data-scraping EZproxy management application to work around this. It's not the most elegant solution, but it meets my needs to be able to script interaction with the proxy server. Hopefully others find it useful as well.
It would have been easier to write that application, though, if EZproxy had an API that I could have tied into, rather than having to data-scrape the status page to load all of the sessions to enable terminating them one-by-one or en masse. I originally did not want to do data-scraping, but the structure of the ezproxy.hst file is not documented, and is considered internal to EZproxy, thus subject to changing between versions. The cleanest way to implement the tool was to go through the web interface and treat it as a management API.
Recently, I added the ability to execute Host Management commands to clear stale/unused entries in the proxy tables. To add that support, I had to run strings against the EZproxy binary to find the embedded HTML page so that I could support all possible operations, not just the ones that were visible on my proxy server at the time I was developing the support.
Again, not an optimal approach, but a functional one, and now about the only thing that the management application does not support is SSL certificates. I don't plan on adding that, but I can suggest certwatch as a utility that can be useful for keeping track of the SSL expiration dates.
Taking a step back, what I feel like I'm really asking for here is a little more of the Unix Philosophy be incorporated into EZproxy. Break up the functionality a little bit, embrace modularity, separate the engine from the interface, decouple the act of management from the mechanism by which the management takes place, and open up the interface so that other tools can interoperate with the server.
Thoughts on the use of technology in a library setting, including the good, the bad, and the ugly of the state of information systems today.
Monday, February 11, 2013
Friday, February 8, 2013
EZProxy wish list: Better scripting support
EZproxy has a built-in expression language that is used in various capacities within config.txt. A common mechanism is to use the expressions during login to set variables that can be used in other parts of the login sequence, or later on in database definitions. I have even seen references to these variables being able to be parsed in the various EZproxy HTML files to do things like add a link in web pages for administrators to navigate to the /admin URL easily.
It is a powerful feature, no doubt, but one that is shrouded in mystery and mystique.
Then there are the conditions and actions settings, which can be used in the user.txt file. A common technique is to use these to override access for specific accounts retrieved from a central account repository.
And while we're talking about scripting, let's not forget about SPUEdit as well. I'm not sure that I totally understand the purpose of this directive, but I think it's intended to be used to provide a way to accommodate legacy links while not having to fill your database stanzas with cruft for old Starting Point Urls (hence the SPU in SPUEdit).
Here's today's challenge, though: Find a good Howto, Tutorial, or Cookbook reference for EZproxy's expression language.
Go ahead, I'll wait...
Couldn't find one either, eh?
This is something that OCLC needs to address in addition to finishing out the EZproxy reference manual. Producing a Cookbook document showing various goals, and how to achieve them using EZproxy's expression language would go a long way towards documenting the expression language, and perhaps open our eyes to ways to harness the power of this facility to accomplish things that we cannot today.
Earlier in this series, I had put for the idea of adopting Lua for scripting within EZproxy for services that needed to perform a authentication handshake to generate a token value for patrons to use to connect to the service.
Why not go all the way, and adopt Lua as the internal scripting language for all of EZproxy? This would give EZproxy the benefit of a mature scripting language with third party library support.
Want to authenticate against a SQL database? You're out of luck today if you are not running Windows and can use ODBC. But with LuaSQL, you could tie into the most popular databases on the market from either platform. Want to go all Web 2.0 and adopt OAuth, OpenID, or some other authentication framework? I'm pretty sure you can find Lua support for it.
This is why opening up EZproxy would be a good thing for OCLC. They would not have to go all the way to open sourcing EZproxy (which I think would be a good thing for them to do), even if all they did was open up and expose APIs and interfaces, and adopt a standard scripting language that could be extended, it would be a fantastic step in the right direction.
It is a powerful feature, no doubt, but one that is shrouded in mystery and mystique.
Then there are the conditions and actions settings, which can be used in the user.txt file. A common technique is to use these to override access for specific accounts retrieved from a central account repository.
And while we're talking about scripting, let's not forget about SPUEdit as well. I'm not sure that I totally understand the purpose of this directive, but I think it's intended to be used to provide a way to accommodate legacy links while not having to fill your database stanzas with cruft for old Starting Point Urls (hence the SPU in SPUEdit).
Here's today's challenge, though: Find a good Howto, Tutorial, or Cookbook reference for EZproxy's expression language.
Go ahead, I'll wait...
Couldn't find one either, eh?
This is something that OCLC needs to address in addition to finishing out the EZproxy reference manual. Producing a Cookbook document showing various goals, and how to achieve them using EZproxy's expression language would go a long way towards documenting the expression language, and perhaps open our eyes to ways to harness the power of this facility to accomplish things that we cannot today.
Earlier in this series, I had put for the idea of adopting Lua for scripting within EZproxy for services that needed to perform a authentication handshake to generate a token value for patrons to use to connect to the service.
Why not go all the way, and adopt Lua as the internal scripting language for all of EZproxy? This would give EZproxy the benefit of a mature scripting language with third party library support.
Want to authenticate against a SQL database? You're out of luck today if you are not running Windows and can use ODBC. But with LuaSQL, you could tie into the most popular databases on the market from either platform. Want to go all Web 2.0 and adopt OAuth, OpenID, or some other authentication framework? I'm pretty sure you can find Lua support for it.
This is why opening up EZproxy would be a good thing for OCLC. They would not have to go all the way to open sourcing EZproxy (which I think would be a good thing for them to do), even if all they did was open up and expose APIs and interfaces, and adopt a standard scripting language that could be extended, it would be a fantastic step in the right direction.
Thursday, February 7, 2013
Raising the bar: Now there is no lawn
Recently I found an issue in augeas that I fixed, so I wanted to be a good netizen and report the problem along with the patch.
I've never needed to contribute to a Fedora Hosted project before, so I do not possess a Fedora Account, which is required for their bug reporting system.
OK, no big deal, their account signup is not too onerous: email, name, password, security Q&A and a math capcha.... A dozen tries later, I finally abandon the idea that I would ever get past the image capcha. The validator must be using the new math, because last time I checked 22+53=75.
They have an audio capcha option, too, let's try that.... I'm guessing it's using the Ogg Vorbis codec, because I couldn't get it to play.
Alright, let's try asking on the IRC channel if the account system is having problems.... Except it's been so long since I've used freenode that I have no idea what my password might have been, so I can't join any channel to ask.
Mailing list! There's a developer mailing list! I'll just drop them a quick note with the patch.
By this point, I've already spent more time just trying to report the bug and the fix than it took to find and fix the bug in the first place.
UNCLE!
Finally I looked through the mailing list and just dropped a message with the patch to one of the maintainers, and he committed the fix -- thanks David!
Once upon a time, the Internet used to be an open and collaborative environment, but these days, it's just wall after wall to keep the pests off the lawn.
I've never needed to contribute to a Fedora Hosted project before, so I do not possess a Fedora Account, which is required for their bug reporting system.
OK, no big deal, their account signup is not too onerous: email, name, password, security Q&A and a math capcha.... A dozen tries later, I finally abandon the idea that I would ever get past the image capcha. The validator must be using the new math, because last time I checked 22+53=75.
They have an audio capcha option, too, let's try that.... I'm guessing it's using the Ogg Vorbis codec, because I couldn't get it to play.
Alright, let's try asking on the IRC channel if the account system is having problems.... Except it's been so long since I've used freenode that I have no idea what my password might have been, so I can't join any channel to ask.
Mailing list! There's a developer mailing list! I'll just drop them a quick note with the patch.
You are not allowed to post to this mailing list, and your message has been automatically rejected. If you think that your messages are being rejected in error, contact the mailing list owner.I really don't feel like joining the list just to post a single patch, because the chances that I'll ever find a bug worth reporting again are pretty slim.
By this point, I've already spent more time just trying to report the bug and the fix than it took to find and fix the bug in the first place.
UNCLE!
Finally I looked through the mailing list and just dropped a message with the patch to one of the maintainers, and he committed the fix -- thanks David!
Once upon a time, the Internet used to be an open and collaborative environment, but these days, it's just wall after wall to keep the pests off the lawn.
Wednesday, February 6, 2013
EZproxy wish list: Embrace the platform
One of EZproxy's greatest strengths is its simplicity.
One of EZproxy's greatest weaknesses is its simplicity.
How can that be? Put simply, by trying to abstract out the underlying platform, EZproxy has to be more than it needs to be.
EZproxy is distributed as a single binary, statically linked, with a self-extracting function to unpack a directory structure, a startup script that is a simple wrapper for the downloaded binary, and even a sample configuration that demonstrates how to get the server up and running within a few minutes of the download finishing.
That sounds great, right? A one-stop shop. Download, install, run, done.
By taking this stance, EZproxy does not embrace the platform that it is being run on, and does not benefit from system services and reap the benefits of following standard conventions. So what's missing?
Log rotation for one. On Linux systems, most (all?) use logrotate to handle rotating, compressing and retention of log files. Installed software drops a file into /etc/logrotate.d, and everything else is taken care of automatically. The closest you can come on this in EZproxy is to use the LogFile directive with the -strftime option. This will allow you to create a separate log file per time period, but it does not address compression, rotation, or retention.
Another issue is hidden among the files extracted by EZproxy: the mimetypes file. This is used mainly for EZproxy's handling of mime types when it is serving files locally from one of the directories under docs. Why is this an issue? Because it is a very minimal file that is installed by EZproxy:
Next there is the startup/shutdown script, which is just a loose wrapper around the EZproxy binary itself. The issue here is that the return values are not compliant with the Linux Standards Base (LSB). This means that other tools written to expect certain behavior from the script will not get the values they are expecting, and thus not be able to manage EZproxy the way other applications can be managed. The most notable current exception is the "status" command handling not returning the expected values for the various states that EZproxy could be in. Word is this behavior will be fixed in one of the 6.x releases.
And then there is filesystem layout in general.
Let's start with PID file handling and lock file handling. In general, a Unix daemon process creates a file containing it's Process ID (PID) that can later be used for checking health of the process and sending signals to the process (HUP to reload, STOP to shutdown, etc), and have a designated place on the system (/var/run). The IPC file (ezproxy.ipc) should be under /var/run as well. Similarly, lock files (ezproxy.lck) belong in /var/lock. Why? Because systems clean up /var/run/* and /var/lock/* when they reboot. This would solve the issue of EZproxy not being able to cleanly start after a server crash because the lock and ipc files are left on disk. Work with the system, not against it.
Then there is log file location (/var/log), configuration file location (/etc), SSL certificate handling (/etc/pki/tls), and the docs directory (/var).
So at the end, what might things look like? Something along these lines:
/etc/ezproxy/config.txt
/etc/ezproxy/user.txt
/etc/ezproxy/ezproxy.key
/etc/pki/tls/private/ezproxy.key
/etc/pki/tls/certs/ezproxy.crt
/usr/sbin/ezproxy
/usr/share/ezproxy-<version>/license.txt
/var/log/ezproxy/audit/<auditfiles>
/var/log/ezproxy/<logfiles>
/var/log/ezproxy/<messagefiles>
/var/run/ezproxy/ezproxy.pid
/var/run/ezproxy/ezproxy.ipc
/var/lock/ezproxy.lck
/var/ezproxy/<html files>
/var/ezproxy/docs/limited
/var/ezproxy/docs/loggedin
/var/ezproxy/docs/public
And there you have a daemon that behaves like just about every other piece of software on the system. This layout lends itself to easy packaging, a fairly straightforward SELinux policy, and does not violate the theory of least surprise.
This structure also opens up the doors for future enhancements. Consider:
/etc/ezproxy/<virtualhost>/config.txt
/etc/ezproxy/<virtualhost>/user.txt
/etc/ezproxy/<virtualhost>/ezproxy.key
In this alternative layout, a command line option (I was going to suggest "-c", but that is already used for network connectivity checking, so maybe "-C" instead) could be used something like this in a real startup script (adapted from vsftpd):
CONFS=`ls /etc/ezproxy/*/config.txt 2>/dev/null`
[ -z "$CONFS" ] && exit 6
for i in $CONFS; do
site=`basename $i .conf`
echo -n $"Starting $prog for $site: "
daemon /usr/sbin/ezproxy -C $i
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
echo
done
One of EZproxy's greatest weaknesses is its simplicity.
How can that be? Put simply, by trying to abstract out the underlying platform, EZproxy has to be more than it needs to be.
EZproxy is distributed as a single binary, statically linked, with a self-extracting function to unpack a directory structure, a startup script that is a simple wrapper for the downloaded binary, and even a sample configuration that demonstrates how to get the server up and running within a few minutes of the download finishing.
That sounds great, right? A one-stop shop. Download, install, run, done.
By taking this stance, EZproxy does not embrace the platform that it is being run on, and does not benefit from system services and reap the benefits of following standard conventions. So what's missing?
Log rotation for one. On Linux systems, most (all?) use logrotate to handle rotating, compressing and retention of log files. Installed software drops a file into /etc/logrotate.d, and everything else is taken care of automatically. The closest you can come on this in EZproxy is to use the LogFile directive with the -strftime option. This will allow you to create a separate log file per time period, but it does not address compression, rotation, or retention.
Another issue is hidden among the files extracted by EZproxy: the mimetypes file. This is used mainly for EZproxy's handling of mime types when it is serving files locally from one of the directories under docs. Why is this an issue? Because it is a very minimal file that is installed by EZproxy:
text/html html htm shtmlThat list covers probably 80% of the files that you are likely to serve, but for the other 20%, you're going to wind up with a mime type like text/plain, which can cause issues when serving binary files. I've even seen issues with HTML files that were created as UTF-8 or UTF-16 files because of the editor they were created with; this is more of an issue with the editor, but still leads to unexpected results.
text/css css
image/gif gif
image/jpeg jpeg jpg jpe
image/png png
image/bmp bmp
image/tiff tiff tif
application/pdf pdf
application/x-javascript js
application/msword doc
application/vnd.ms-powerpoint ppt
application/vnd.ms-excel xls
application/vnd.openxmlformats docx pptx xlsx
application/octet-stream bin exe
application/zip zip
audio/mpeg mp3
Next there is the startup/shutdown script, which is just a loose wrapper around the EZproxy binary itself. The issue here is that the return values are not compliant with the Linux Standards Base (LSB). This means that other tools written to expect certain behavior from the script will not get the values they are expecting, and thus not be able to manage EZproxy the way other applications can be managed. The most notable current exception is the "status" command handling not returning the expected values for the various states that EZproxy could be in. Word is this behavior will be fixed in one of the 6.x releases.
And then there is filesystem layout in general.
Let's start with PID file handling and lock file handling. In general, a Unix daemon process creates a file containing it's Process ID (PID) that can later be used for checking health of the process and sending signals to the process (HUP to reload, STOP to shutdown, etc), and have a designated place on the system (/var/run). The IPC file (ezproxy.ipc) should be under /var/run as well. Similarly, lock files (ezproxy.lck) belong in /var/lock. Why? Because systems clean up /var/run/* and /var/lock/* when they reboot. This would solve the issue of EZproxy not being able to cleanly start after a server crash because the lock and ipc files are left on disk. Work with the system, not against it.
Then there is log file location (/var/log), configuration file location (/etc), SSL certificate handling (/etc/pki/tls), and the docs directory (/var).
So at the end, what might things look like? Something along these lines:
/etc/ezproxy/config.txt
/etc/ezproxy/user.txt
/etc/ezproxy/ezproxy.key
/etc/pki/tls/private/ezproxy.key
/etc/pki/tls/certs/ezproxy.crt
/usr/sbin/ezproxy
/usr/share/ezproxy-<version>/license.txt
/var/log/ezproxy/audit/<auditfiles>
/var/log/ezproxy/<logfiles>
/var/log/ezproxy/<messagefiles>
/var/run/ezproxy/ezproxy.pid
/var/run/ezproxy/ezproxy.ipc
/var/lock/ezproxy.lck
/var/ezproxy/<html files>
/var/ezproxy/docs/limited
/var/ezproxy/docs/loggedin
/var/ezproxy/docs/public
And there you have a daemon that behaves like just about every other piece of software on the system. This layout lends itself to easy packaging, a fairly straightforward SELinux policy, and does not violate the theory of least surprise.
This structure also opens up the doors for future enhancements. Consider:
/etc/ezproxy/<virtualhost>/config.txt
/etc/ezproxy/<virtualhost>/user.txt
/etc/ezproxy/<virtualhost>/ezproxy.key
In this alternative layout, a command line option (I was going to suggest "-c", but that is already used for network connectivity checking, so maybe "-C" instead) could be used something like this in a real startup script (adapted from vsftpd):
CONFS=`ls /etc/ezproxy/*/config.txt 2>/dev/null`
[ -z "$CONFS" ] && exit 6
for i in $CONFS; do
site=`basename $i .conf`
echo -n $"Starting $prog for $site: "
daemon /usr/sbin/ezproxy -C $i
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
echo
done
This structure would allow a single server to run multiple instances of EZproxy, with a unique configuration file per instance, something that you cannot do today without multiple installations of EZproxy itself. Going down that route today is not an effortless path: You will need to write a custom startup/shutdown script that can handle starting N independent instances of EZproxy. Today you would have to worry about maintaining N copies of EZproxy, where the proposed structure would allow you to use just a single EZproxy binary to manage multiple sites, so there would be less systems management overhead as well.
Embrace the platform, reap the benefits.
Tuesday, February 5, 2013
EZproxy wish list: IPv6 support
Of all the wish list items that I have mentioned, this is one that OCLC has committed to, so this is technically more of an "anxiously awaiting" rather than "wished for", but this way we can cross an item off the list when OCLC ship the 6.0 version of EZproxy.
OCLC has stated that the 6.0 release (slated for March 2013) will include support for IPv6, and will build upon the support in subsequent updates. Exactly what we can expect in the initial version is not crystal clear, but hopefully listening on IPv6 and being able to send requests to databases that are on IPv4 networks will be a part of the supported functionality of that initial release.
Last year, OCLC hosted a virtual users group meeting on IPv6 where they outlined their IPv6 plans. In that meeting, it sounds like the first build that supports IPv6 may only support IPv6 to IPv6 connections. What I'm waiting to see is if it is going to be supported for EZproxy answer to IPv6 connections but connect users to IPv4 services, as that will be the most common scenario in the short term with IPv6 clients connecting to databases that are still running on IPv4 addresses.
In the diagram above it makes it seem that 6to4 handling may not be part of the features supported for the first iteration. The discussion around this slide was saying that the "ADC" (load balancers to us old-timers) would be handling the network protocol translation, which imply that the vendors will be responsible for putting up IPv6 to IPv4 devices to accept IPv6 connections.
That could just be a shortcoming of the amount of space that was available when making that graphic, but they do not show a dual-stack EZproxy server as part of the setup, rather what appears to be a separate EZproxy instance for IPv4 and IPv6. I had asked about this in the Q&A portion of the presentation, but it was missed in the initial flurry of questions.
Perhaps the following graphic shows the desired dual-stack functionality better:
What this hopefully expresses is that clients can connect to the proxy from either protocol (IPv4 or IPv6) and connect to web servers across either protocol, regardless of which network the request originated.
From a programming point of view, once the connection is accepted on a IPv6 socket, there should be no problem copying the TCP payload to an outbound IPv4 socket for a connection to the vendor, so I am really expecting the first release to be able to handle this.
The good news is there is not much time left to wait before the 6.0 beta should be available. I for one am hoping to be a happy camper, as we already see native IPv6 traffic, and EZproxy is the last piece of our infrastructure that is not IPv6 ready. If the initial release does not support IPv6 to IPv4 connections, I may have to get creative on the proxy's connection to the backbone network instead...
OCLC has stated that the 6.0 release (slated for March 2013) will include support for IPv6, and will build upon the support in subsequent updates. Exactly what we can expect in the initial version is not crystal clear, but hopefully listening on IPv6 and being able to send requests to databases that are on IPv4 networks will be a part of the supported functionality of that initial release.
Last year, OCLC hosted a virtual users group meeting on IPv6 where they outlined their IPv6 plans. In that meeting, it sounds like the first build that supports IPv6 may only support IPv6 to IPv6 connections. What I'm waiting to see is if it is going to be supported for EZproxy answer to IPv6 connections but connect users to IPv4 services, as that will be the most common scenario in the short term with IPv6 clients connecting to databases that are still running on IPv4 addresses.
![]() |
| Short term IPv6 slide from the user's group presentation |
That could just be a shortcoming of the amount of space that was available when making that graphic, but they do not show a dual-stack EZproxy server as part of the setup, rather what appears to be a separate EZproxy instance for IPv4 and IPv6. I had asked about this in the Q&A portion of the presentation, but it was missed in the initial flurry of questions.
Perhaps the following graphic shows the desired dual-stack functionality better:
What this hopefully expresses is that clients can connect to the proxy from either protocol (IPv4 or IPv6) and connect to web servers across either protocol, regardless of which network the request originated.
From a programming point of view, once the connection is accepted on a IPv6 socket, there should be no problem copying the TCP payload to an outbound IPv4 socket for a connection to the vendor, so I am really expecting the first release to be able to handle this.
The good news is there is not much time left to wait before the 6.0 beta should be available. I for one am hoping to be a happy camper, as we already see native IPv6 traffic, and EZproxy is the last piece of our infrastructure that is not IPv6 ready. If the initial release does not support IPv6 to IPv4 connections, I may have to get creative on the proxy's connection to the backbone network instead...
Monday, February 4, 2013
EZproxy wish list: Structured configuration file
A common point of confusion among EZproxy users arises when they start using position sensitive directives in the EZproxy configuration file.
Some rules, like the SSL Cipher directives, must be positioned before other directives (LoginPortSSL in this case).
Others turn certain features on and have a complimentary directive that turns them off (Option DomainCookieOnly / Option Cookie; AutoLoginIP / ExcludeIP / IncludeIP; etc)
Getting to know all of these directives, their relationships, when to use, and in some cases when to not use them can be a steep learning curve for new EZproxy users.
The solution to several of these issues would be to adopt a new structured configuration file format, one similar to Apache HTTPD.
Let's take a look at what a before and after might look like for a few stanzas:
Option DomainCookieOnly
Title -hide EBSCO LinkSource
URL http://linksource.ebsco.com
HJ linksource.ebsco.com
Option Cookie
Here's what this might look like if the Apache HTTPD style were adopted:
<Database "EBSCO LinkSource">
HideTitle
URL http://linksource.ebsco.com
HJ linksource.ebsco.com
Option DomainCookieOnly
</Database>
It's not a dramatic change, but now it is clear what the DomainCookieOnly is limited in scope to the EBSCO LinkSource database. It eliminates the possibility that the "Option Cookie" line is forgotten and impacts a different database stanza.
Here's another idea:
URL http://alexanderstreet.com/
Domain alexanderstreet.com
Host ahiv.alexanderstreet.com
...
Host womv.alexanderstreet.com
Almost a screen full of Host directives complete that stanza!
Why not enable making it simpler, like so:
<Database "Alexander Street Press">
Domain alexanderstreetpress.com
Host *.alexanderstreetpress.com
</Database>
Those seem pretty straightforward, and easy to follow. Now let's look at some core configuration.
Before:
Interface Any
LoginPort 80
Option ForceHTTPSLogin
Some rules, like the SSL Cipher directives, must be positioned before other directives (LoginPortSSL in this case).
Others turn certain features on and have a complimentary directive that turns them off (Option DomainCookieOnly / Option Cookie; AutoLoginIP / ExcludeIP / IncludeIP; etc)
Getting to know all of these directives, their relationships, when to use, and in some cases when to not use them can be a steep learning curve for new EZproxy users.
The solution to several of these issues would be to adopt a new structured configuration file format, one similar to Apache HTTPD.
Let's take a look at what a before and after might look like for a few stanzas:
Option DomainCookieOnly
Title -hide EBSCO LinkSource
URL http://linksource.ebsco.com
HJ linksource.ebsco.com
Option Cookie
Here's what this might look like if the Apache HTTPD style were adopted:
<Database "EBSCO LinkSource">
HideTitle
URL http://linksource.ebsco.com
HJ linksource.ebsco.com
Option DomainCookieOnly
</Database>
It's not a dramatic change, but now it is clear what the DomainCookieOnly is limited in scope to the EBSCO LinkSource database. It eliminates the possibility that the "Option Cookie" line is forgotten and impacts a different database stanza.
Here's another idea:
URL http://alexanderstreet.com/
Domain alexanderstreet.com
Host ahiv.alexanderstreet.com
...
Host womv.alexanderstreet.com
Almost a screen full of Host directives complete that stanza!
Why not enable making it simpler, like so:
<Database "Alexander Street Press">
Domain alexanderstreetpress.com
Host *.alexanderstreetpress.com
</Database>
Those seem pretty straightforward, and easy to follow. Now let's look at some core configuration.
Before:
Interface Any
LoginPort 80
Option ForceHTTPSLogin
Option DisableSSL56bit
Option DisableSSLv2
LoginPortSSL 443
IncludeFile databases/vendorA
IncludeFile databases/vendorB
IncludeFile databases/vendorC
As mentioned above, there is an ordering that needs to be observed for those directives to work, and do what they are intended. If you have a group of Option directives in you configuration file that happens to appear after the LoginPort, and blindly add the DisableSSL settings, you will not actually disable the weak SSL cipher support.
What if that were configured more like Apache VirtualHosts:
<VirtualHost [IP Address #1]:80>
IncludeFile databases/vendorA
<Authentication ReferringURL>
URL http://lib.example.edu/
</Authentication>
</VirtualHost >
<VirtualHost [IP Address #2]:80>
IncludeFile databases/vendorB
<Authentication Ticket>
TimeValid 10
MD5 somekey
Expired Deny expired.html
</Authentication>
</VirtualHost >
<VirtualHost [IP Address #1]:443>
ForceHTTPSLogin
DisableSSL56bit
DisableSSLv2
IncludeFile databases/vendorC
<Authentication File>
URL file:///path/to/users.txt
</Authentication>
</VirtualHost >
Here we have 3 proxy instances on 2 different IP addresses, one setup for SSL. The first does referring URL authentication to Vendor A, the second does ticket-based authentication for Vendor B, and the third uses SSL for Vendor C for a subset of users.
An approach like this would make the multi-site proxy approach easier to setup. The nightmare scenario where you have multiple campus locations, each teaching different programs, each with different capabilities when it comes to user authentication, each with different sophistication levels of the web site that patrons are going to be using.
Setting up something as complex as that example in EZproxy today with its flat configuration would require the use of Groups, multiple Interface directives, very careful ordering of directives, and extensive testing. I could probably generate a working equivalent, but it would take a bit of time to work it all out and make sure that it was functioning as designed.
With a structured configuration format like the strawman proposal above, you can see how it is obvious which rules are applying to which database, without having to scour the file for context, and with the right hierarchy of directives, the amount of time spent designing and testing such a setup can be reduced significantly.
Friday, February 1, 2013
EZproxy wish list: modular interface for authentication and services
Between the built-in authentication support and the catch-all CGI mechanism, EZproxy does a decent job of handling a diverse set of authentication scenarios. What is implemented is the 80-90% use case, which -- as a developer myself -- I can appreciate. Once you step outside the realm of what is implemented, though, about the only option left available are to use the CGI interface as glue logic into other systems. This can be made to work for many things, but not everything.
For example, RADIUS is supported, but I do not know of any way to flag an account in RADIUS as an administrator account for EZproxy. Nor is RADIUS accounting support implemented (not that many people would use accounting in a typical setting, but in a hosted environment it could open up interesting options for usage-based billing).
One thing that I would really like to have, though, is better Kerberos support. There is already some level of Kerberos built into EZproxy for Active Directory support, but I cannot setup a SPNEGO authenticated connection leveraging my existing non-Microsoft Kerberos servers, because Kerberos is not able to be configured independently of Active Directory.
What would be nice is if OCLC would adopt a modular interface for EZproxy so that those of us with both the skill set as well as the proverbial itch can write extensions to EZproxy that close the feature gap on the 10-20% case that is left out.
If OCLC does go down the modularization route, let's not forget about service handling. Look at current services that require a magic token to connect, like Books24x7, Netlibrary, eBrary, etc. These services perform a handshake with the vendor to retrieve a token value, and then redirect the user's browser into the service using the token as the authentication key.
There is no reason that EZproxy could not use a scripting language like Lua (which is the scripting language behind a surprising amount of commercial programs and games) to perform these handshakes, making the service handling as flexible as the database stanzas are now. With the right design, the scripting interface might even be able to make some of the database stanzas simpler.
Take the recent phenomenon of .NET applications that use the _VIEWSTATE variable to maintain application state as described in this MSDN article. It is just screaming for better EZproxy support. Creative use of the Find/Replace directives can handle populating the username and password fields, and then inject JavaScript into the page to auto-submit the form for a seamless login, but each of these has to be hand-crafted today.
Wouldn't it be nice if EZproxy used Lua as a macro language, and the EZproxy user community could write a function to handle this case more gracefully and share that code the same way we share database stanzas today?
For example, RADIUS is supported, but I do not know of any way to flag an account in RADIUS as an administrator account for EZproxy. Nor is RADIUS accounting support implemented (not that many people would use accounting in a typical setting, but in a hosted environment it could open up interesting options for usage-based billing).
One thing that I would really like to have, though, is better Kerberos support. There is already some level of Kerberos built into EZproxy for Active Directory support, but I cannot setup a SPNEGO authenticated connection leveraging my existing non-Microsoft Kerberos servers, because Kerberos is not able to be configured independently of Active Directory.
What would be nice is if OCLC would adopt a modular interface for EZproxy so that those of us with both the skill set as well as the proverbial itch can write extensions to EZproxy that close the feature gap on the 10-20% case that is left out.
If OCLC does go down the modularization route, let's not forget about service handling. Look at current services that require a magic token to connect, like Books24x7, Netlibrary, eBrary, etc. These services perform a handshake with the vendor to retrieve a token value, and then redirect the user's browser into the service using the token as the authentication key.
There is no reason that EZproxy could not use a scripting language like Lua (which is the scripting language behind a surprising amount of commercial programs and games) to perform these handshakes, making the service handling as flexible as the database stanzas are now. With the right design, the scripting interface might even be able to make some of the database stanzas simpler.
Take the recent phenomenon of .NET applications that use the _VIEWSTATE variable to maintain application state as described in this MSDN article. It is just screaming for better EZproxy support. Creative use of the Find/Replace directives can handle populating the username and password fields, and then inject JavaScript into the page to auto-submit the form for a seamless login, but each of these has to be hand-crafted today.
Wouldn't it be nice if EZproxy used Lua as a macro language, and the EZproxy user community could write a function to handle this case more gracefully and share that code the same way we share database stanzas today?
Subscribe to:
Posts (Atom)

