Running Sage through Apache2 with Reverse Proxy

877 views
Skip to first unread message

Jonathan Frankel

unread,
Sep 10, 2011, 2:13:33 PM9/10/11
to sage-s...@googlegroups.com
Hi all,

I've been beating my head against the wall for hours over this now. I'd like to run Sage Notebook server from my home server, which also has a few other web based apps running through Apache. Obviously, I want to enable ssl -- and I already have a certificate for my own domain that I'm using to run those other apps.

This is going to be a long post, so I'll get straight to the questions first in case someone already knows the answer. My goal is to be able to go to https://www.mydomain.com/sage in order to use  the sage notebook server.

  1. Is there a way to set the context path for the Sage notebook server? What I mean is, normally you have browse to http://127.0.0.1:8000 to get to the notebook server, but is there a setting that will allow you to go to http://127.0.0.1:8000/sage to see it?
  2. If that's not possible, what are the exact apache config settings I need to use to get reverse proxy running correctly. Other sources (http://wiki.sagemath.org/SageServer) don't consider an environment with other web services. What if I'm already using reverse proxy for another service?
  3. If that's not possible (or nobody knows) -- I have my own ssl certificate that I got from startssl.com. How can I get Sage to use my verified certificate rather than the one it generates?

First off, my setup uses two VBox virtual machines -- one Ubuntu 10.04 (64-bit), and one Windows 2008 R2 (64-bit). The physical server is Ubuntu 8.04 (AMD64, 64-bit). The Ubuntu VM is running Apache2 and subversion, and the Windows VM is running a bunch of media services. What I'm trying to do is run Sage on the physical server, and use Apache2 on the Ubuntu VM as the gateway for it. The reason why is that I'm already using Apache2 as a gateway to other services on my Windows VM, so port 443 is already forwarded to the Ubuntu VM. (Why am I running Apache in a VM? Uhm...long story. It doesn't really matter for this.)

This page (http://wiki.sagemath.org/SageServer) makes a recommendation that doesn't work for my setup. Here's the relevant Apache config section:

<VirtualHost *:80>   
ServerName YOUR_SERVER_NAME

ProxyRequests Off
ProxyPreserveHost On

<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyPass / http://localhost:8000/
ProxyPassReverse / http://localhost:8000/

 DocumentRoot /
 <Location />   DefaultType text/html
 </Location>

   ErrorLog /var/log/apache2/error.log

   # Possible values include: debug, info, notice, warn, error, crit,
   # alert, emerg.
   LogLevel warn

   CustomLog /var/log/apache2/access.log combined
   ServerAdmin YOUR_SERVER_ADMIN_EMAIL_ADDRESS
 </VirtualHost>

The problem with this is that 
ProxyPass and ProxyPassReverse both send everything to the sage notebook server. This is for a setup with a dedicated domain; i.e., http://www.mydomain.com will be the url for sage. I want to use https://www.mydomain.com/sage.

In order to do that I first tried these directives in the "default-ssl" config file:

ProxyPass /sage http://192.168.2.140:8000/
ProxyPassReverse /sage http://192.168.2.140:8000/

The problem with this is that all of the links in the html work improperly, meaning images, css, and javascript don't load. The reason is that the html uses paths like "/path/to/image.png", which gets resolved on the client side to https://www.mydomain.com/path/to/image.png instead of https://www.mydomain.com/sage/path/to/image.png. This also means that the submit button for the login directs to https://www.mydomain.com/home instead of https://www.mydomain.com/sage/home.

I think the easiest fix for this is if there was some setting in Sage that allows you (on the local network) to browse to http://192.168.2.140/sage. This is what my music server does -- it allows me to change the context path. The directives I use for that (which work perfectly) are:

ProxyPass /music http://192.168.2.140:8181/music
ProxyPassReverse /music http://192.168.2.140:8181/music

Okay, so I tried working around this problem. I discovered that I should be able to use mod_proxy_html to resolve URIs properly. I used information from these two sites (http://wlug.org.nz/ApacheReverseProxy and http://www.apachetutor.org/admin/reverseproxies) to come up with a configuration that works sort of half way. (Following the config directives of either site by itself either resulted in the same issues or the notebook server being totally inaccessible.) Here's the config I used:

 ProxyPass /sage/ http://192.168.2.140:8000/
        ProxyHTMLURLMap http://192.168.2.140:8000 /sage
        <Location /sage/>
                Order deny,allow
                Allow from all
                ProxyPassReverse /
                SetOutputFilter proxy-html
                ProxyHTMLURLMap / /sage/
        </Location>

At first, when I browse to https://www.mydomain.com/sage/ I found success! The css, images, and everything loaded properly! But when I try to log in, for some reason I get redirected to http://192.168.2.140:8000/. I just don't understand why this happens, and I've tried playing around with the directives, but I don't have any more success than getting the first login page to show up correctly. After that it sends my browser to the local network location.

Has anyone gotten a setup like what I'm trying to do to run successfully?

Right now, I have my router forwarding port 8000 to the sage notebook server and "secure=True" option set. I also have a redirect rule in Apache so that I can browse to http://www.mydomain.com/sage and it will redirect me to https://www.mydomain.com:8000. But this is less than ideal; first it just bugs me having the port in the URL -- it seems unclean to me and might confuse other people who try this out on my server.

Second, and much more importantly, this requires sage to use its own ssl certificate, which isn't trusted and causes the browser to freak out and throw that scary warning that will intimidate regular users.

At the very least, I'd like to be able to install my own verified ssl certificate so that those warnings don't happen. I haven't been able to find a .crt or .key file, but I found about a dozen .pem files all over sage's python directory structure. Is there anything I can do to replace the ssl certificate with my own?

Thanks for any help!

Jonathan

erikson1970

unread,
Jul 4, 2012, 9:01:36 PM7/4/12
to sage-s...@googlegroups.com
Jonathan - Any luck solving this problem?  I'm banging my head against the same wall.  Reverse proxying through Apache seems to work fine with my Subsonic music server but my Sage session is unhappy with it. same symptoms. 

Leif 

Nils Bruin

unread,
Jul 5, 2012, 1:54:23 AM7/5/12
to sage-s...@googlegroups.com
On Saturday, September 10, 2011 11:13:33 AM UTC-7, Jonathan Frankel wrote:
At the very least, I'd like to be able to install my own verified ssl certificate so that those warnings don't happen. I haven't been able to find a .crt or .key file, but I found about a dozen .pem files all over sage's python directory structure. Is there anything I can do to replace the ssl certificate with my own?

I think those certificates are stored in your .sage directory:

sage: !ls $DOT_SAGE/notebook
cert.cfg  private.pem  public.pem

You can probably replace those with certificates of your choosing.

Michael Waters

unread,
Aug 7, 2015, 2:16:40 PM8/7/15
to sage-support
Hi All -
I'm currently having the exact same problem.  I have a reverse proxy set up for RStudio through Apache and it works fine.  However, the reverse proxy setup doesn't seem to work for SAGE for the reasons described above.
Has anyone overcome this issue yet?
Thanks
Message has been deleted

kcrisman

unread,
Aug 14, 2015, 9:45:05 AM8/14/15
to sage-support, Jonathan Gutow
 Just cc:ing as in the other thread.

Jonathan Gutow

unread,
Aug 14, 2015, 2:51:16 PM8/14/15
to sage-support
Saw this through kcrisman's forward.  I think I can help.  I routinely do what I think you are are asking to do.  I have found that proxypass and proxyreverse do not work well.  I use the rewrite engine with proxying and the VirtualHostMonster facilities (makes sure links in sage point the correct place) that are part of the sage server.  Here is an example of my apache proxy set up (scrubbed to protect security, so the addresses are all made up). I am running two sage servers and a joomla server on the same machine.

<IfModule mod_ssl.c>
   
<VirtualHost *:443>
        ServerAdmin admin@some-email
        DocumentRoot /var/www
       
<Directory />
                Options FollowSymLinks
                AllowOverride None
       
</Directory>
       
<Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
       
</Directory>

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on

        #   A self-signed (snakeoil) certificate can be created by installing
        #   the ssl-cert package. See
        #   /usr/share/doc/apache2/README.Debian.gz for more info.
        #   If both key and certificate are stored in the same file, only the
        #   SSLCertificateFile directive is needed.
        SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

        #   Server Certificate Chain:
        #   Point SSLCertificateChainFile at a file containing the
        #   concatenation of PEM encoded CA certificates which form the
        #   certificate chain for the server certificate. Alternatively
        #   the referenced file can be the same as SSLCertificateFile
        #   when the CA certificates are directly appended to the server
        #   certificate for convinience.
        #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt

        #   Certificate Authority (CA):
        #   Set the CA certificate verification path where to find CA
        #   certificates for client authentication or alternatively one
        #   huge file containing all of them (file must be PEM encoded)
        #   Note: Inside SSLCACertificatePath you need hash symlinks
        #         to point to the certificate files. Use the provided
        #         Makefile to update the hash symlinks after changes.
        #SSLCACertificatePath /etc/ssl/certs/
        #SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt

        #   Certificate Revocation Lists (CRL):
        #   Set the CA revocation path where to find CA CRLs for client
        #   authentication or alternatively one huge file containing all
        #   of them (file must be PEM encoded)
        #   Note: Inside SSLCARevocationPath you need hash symlinks
        #         to point to the certificate files. Use the provided
        #         Makefile to update the hash symlinks after changes.
        #SSLCARevocationPath /etc/apache2/ssl.crl/
        #SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl

        #   Client Authentication (Type):
        #   Client certificate verification type and depth.  Types are
        #   none, optional, require and optional_no_ca.  Depth is a
        #   number which specifies how deeply to verify the certificate
        #   issuer chain before deciding the certificate is not valid.
        #SSLVerifyClient require
        #SSLVerifyDepth  10

        #   SSL Engine Options:
        #   Set various options for the SSL engine.
        #   o FakeBasicAuth:
        #     Translate the client X.509 into a Basic Authorisation.  This means that
        #     the standard Auth/DBMAuth methods can be used for access control.  The
        #     user name is the `one line' version of the client's X.509 certificate.
        #     Note that no password is obtained from the user. Every entry in the user
        #     file needs this password: `xxj31ZMTZzkVA'.
        #   o ExportCertData:
        #     This exports two additional environment variables: SSL_CLIENT_CERT and
        #     SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
        #     server (always existing) and the client (only existing when client
        #     authentication is used). This can be used to import the certificates
        #     into CGI scripts.
        #   o StdEnvVars:
        #     This exports the standard SSL/TLS related `SSL_*' environment variables.
        #     Per default this exportation is switched off for performance reasons,
        #     because the extraction step is an expensive operation and is usually
        #     useless for serving static content. So one usually enables the
        #     exportation for CGI and SSI requests only.
        #   o OptRenegotiate:
        #     This enables optimized SSL connection renegotiation handling when SSL
        #     directives are used in per-directory context.
        #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
       
<FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars +ExportCertData
       
</FilesMatch>
       
<Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
       
</Directory>

        #   SSL Protocol Adjustments:
        #   The safe and default but still SSL/TLS standard compliant shutdown
        #   approach is that mod_ssl sends the close notify alert but doesn't wait for
        #   the close notify alert from client. When you need a different shutdown
        #   approach you can use one of the following variables:
        #   o ssl-unclean-shutdown:
        #     This forces an unclean shutdown when the connection is closed, i.e. no
        #     SSL close notify alert is send or allowed to received.  This violates
        #     the SSL/TLS standard but is needed for some brain-dead browsers. Use
        #     this when you receive I/O errors because of the standard approach where
        #     mod_ssl sends the close notify alert.
        #   o ssl-accurate-shutdown:
        #     This forces an accurate shutdown when the connection is closed, i.e. a
        #     SSL close notify alert is send and mod_ssl waits for the close notify
        #     alert of the client. This is 100% SSL/TLS standard compliant, but in
        #     practice often causes hanging connections with brain-dead browsers. Use
        #     this only for browsers where you know that their SSL implementation
        #     works correctly.
        #   Notice: Most problems of broken clients are also related to the HTTP
        #   keep-alive facility, so you usually additionally want to disable
        #   keep-alive for those clients, too. Use variable "nokeepalive" for this.
        #   Similarly, one has to force some clients to use HTTP/1.0 to workaround
        #   their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
        #   "force-response-1.0" for this.
        BrowserMatch "MSIE [2-6]" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0
        # MSIE 7 and newer should be able to use keepalive
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
# SSL proxying
  SSLProxyEngine on
  SSLProxyVerify none
  SSLProxyCheckPeerCN off
  SSLProxyCheckPeerExpire off
  SSLProxyCheckPeerName off

# rewrites
  RewriteEngine On
  RewriteOptions Inherit

# Secured Sage server and test joomla insatllation
  RewriteCond %{REQUEST_URI} !/joomla
  RewriteRule ^/sagetest(.*) http://localhost:8888/virtualhostbase/https/PPP.VVV.YYY.XXX:443/sagetest$1 [P]
  RewriteRule ^/sage(.*) http://localhost:8081/virtualhostbase/https/PPP.VVV.
YYY.XXX:443/sage$1 [P]

   
</VirtualHost>
</IfModule>

I haven't been teaching the classes that use my sage server for a while, so haven't updated past 6.4.1.  However, I think the notebook/server has not been changed (I did the work to make this proxying work).

Jonathan

Jonathan Gutow

unread,
Aug 25, 2015, 10:40:32 PM8/25/15
to sage-support
I can verify that the version of the notebook in sage-6.8 does not support proper proxying.  I don't have much time to devote to it, but will see if I can determine what happened to the code I submitted.  It appears that I may have the only version of sage running this properly.  I can probably make my git repository available with instructions on how to replace the notebook without proxy support with one that does.

Jonathan

kcrisman

unread,
Aug 26, 2015, 10:20:28 PM8/26/15
to sage-support

I can verify that the version of the notebook in sage-6.8 does not support proper proxying.  I don't have much time to devote to it, but will see if I can determine what happened to the code I submitted.  It appears that I may have the only version of sage running this properly.  I can probably make my git repository available with instructions on how to replace the notebook without proxy support with one that does.


Jonathan, can I confirm that it would only be your code at https://github.com/sagemath/sagenb/pull/328 that would be necessary?  If someone else (such as Michael or one of the original posters!) can test this then I think we could merge that in sagenb proper, which I agree would be very nice.

If I recall correctly, I know nothing about proxying and so couldn't review it with integrity, and there was a semi-important issue of a number of changed paths to things like published worksheets which could cause problems in some circumstances (such as published links on other pages or even in published dead tree articles!). 

Jonathan Gutow

unread,
Aug 27, 2015, 5:00:06 PM8/27/15
to sage-support
That pull request has aged out as the notebook is now version 0.11.4.  However, I have refactored things to work with 0.11.4 and sage post 6.4.  This is now accessible in my git repository https://github.com/gutow/sagenb_slickgrid in the branch merge_11_4.  I have not merged with my master because I haven't finished testing.  However, in case others want to test here are instructions for doing it.

0.5) If you do not have git installed on your machine install it.
1) clone my git repository to a directory in the same account as your test sage instance runs from (eg. "git clone https://github.com/gutow/sagenb_slickgrid.git").
2) navigate to the cloned repository and issue the command "git branch merge_11_4" to switch to the correct branch of the repository.
3) cd to "local/lib/python/site-packages/sagenb*" in your sage install.  This should put you inside your sagenb egg.
4) rename the sagenb directory you find there to something else (eg. "mv sagenb sagenb_old").
5) create a symbolic link with the absolute path to the my repository (eg. "ln -s /home/<sage account>/sagenb_slickgrid/sagenb  sagenb") to replace the old sagenb directory.

Now when you start sage it will use the updated version of the notebook which should handle proxying properly.  I suggest reading the documentation for the notebook command, which I tried to update to explain the proper usage of the proxying.  See in particular notes on the 'site_name' parameter.  You get this documentation with the sage command "notebook?".

Hope this helps.  Also, if others look at this I am more likely to be able to find all the bugs that need to be squashed.

Jonathan

Jonathan Gutow

unread,
Aug 27, 2015, 5:05:20 PM8/27/15
to sage-support
Another option for simple testing is to create an account on my test server at this address.  However, it would be nice if somebody tried this on their own server.

If you do create an account please let me know if you find any problems.  Please do not try to run really large calculations on this as the test server is an old scrounged machine that I use for this purpose.  It has limited capacity. 

The link is: https://141.233.196.149/sagetest/.

Jonathan

Jonathan Gutow

unread,
Aug 28, 2015, 1:35:31 PM8/28/15
to sage-support
My test server will be unavailable this weekend as my campus will have no electricity. I will bring it back up as soon as possible on Monday.

Jonathan

Jonathan Gutow

unread,
Sep 1, 2015, 12:16:57 PM9/1/15
to sage-support
My test server at https://141.233.196.149/sagetest/ is back up and running.  I think I have found all the problems.  I'm just about ready to push my fixes into my master branch, convert my production server to 6.8 using this and put in a new pull request.  I will wait a couple of days hoping that somebody interested in this will do a little testing.

Jonathan

kcrisman

unread,
Sep 2, 2015, 9:39:56 PM9/2/15
to sage-support

My test server at https://141.233.196.149/sagetest/ is back up and running.  I think I have found all the problems.  I'm just about ready to push my fixes into my master branch, convert my production server to 6.8 using this and put in a new pull request.  I will wait a couple of days hoping that somebody interested in this will do a little testing.

Jsmols in published worksheet work, I didn't know that was supported but I guess it shouldn't surprise me!  Security risk? 

When one tries to create an account the html for the challenge is just text, ascii of the html.  So that is not so good, though I don't know if it's related to your changes or not.

Jonathan Gutow

unread,
Sep 3, 2015, 10:33:46 AM9/3/15
to sage-support


On Wednesday, September 2, 2015 at 8:39:56 PM UTC-5, kcrisman wrote:

My test server at https://141.233.196.149/sagetest/ is back up and running.  I think I have found all the problems.  I'm just about ready to push my fixes into my master branch, convert my production server to 6.8 using this and put in a new pull request.  I will wait a couple of days hoping that somebody interested in this will do a little testing.

Jsmols in published worksheet work, I didn't know that was supported but I guess it shouldn't surprise me!  Security risk? 
This should work...I'll check.  I thought that was working...

When one tries to create an account the html for the challenge is just text, ascii of the html.  So that is not so good, though I don't know if it's related to your changes or not.
 I don't think I touched anything related to this, but will check it with a version not running my changes and see if I can figure it out.

Thanks

kcrisman

unread,
Sep 3, 2015, 11:00:23 AM9/3/15
to sage-support
Jsmols in published worksheet work, I didn't know that was supported but I guess it shouldn't surprise me!  Security risk? 
This should work...I'll check.  I thought that was working...


It DOES work but I was surprised because I wasn't expecting it to :) since I hadn't used that functionality.
 

Jonathan Gutow

unread,
Sep 4, 2015, 12:03:59 PM9/4/15
to sage-support
OK, I found the code I accidentally picked up from someone's branch.  It was messing up the text encoding for  templates. 

Anyway, the simple challenge in self-registration now works along with proxying.  I also fixed the registration cancel button which did not work.

I have pushed this to my main branch and will now put in a new pull request.

Jonathan

Jonathan Gutow

unread,
Sep 4, 2015, 2:19:01 PM9/4/15
to sage-support
Actually, I just updated pull request #328 (https://github.com/sagemath/sagenb/pull/328) as it keeps track of updates to my master branch.
Reply all
Reply to author
Forward
0 new messages