Go to page content

Running on Port 80 and Port 443

[0.7+] Using standard ports helps visitors discover your page and removes the awkward port number from URLs.

Contributed by: Scott Finnie and Alain O'Dea

Why

It is beneficial to run a webserver's HTTP and HTTPS services on standard ports.  Doing this aids discovery and lends a air of polish while a non-standard port number suggests something is incomplete.

Assumptions

  1. zotonic >=0.7 installed
  2. Tested on ubuntu 10.04 Server & linux mint 10. Should work on other debian-based distros.
  3. Will not work with ipv6 addresses - authbind doesn't support ipv6.

How

Overview

*nix systems only allow the superuser (root) to bind to ports below 1024. HTTP & HTTPS use ports 80 & 443 respectively. So setting up zotonic to serve from those ports without running as superuser presents a problem.

There are several approaches to solving this problem, e.g.

  • running behind another web server/proxy such as nginx or varnish (see e.g. http://zotonic.com/documentation/777/deployment)

  • using iptables to forward from port 80/443 to ports > 1024 to which zotonic listens

  • using authbind. Authbind (http://en.wikipedia.org/wiki/Authbind) provides a means for non-root users to bind directly to ports below 1024.

  • using Linux capabilities and setcap

There are pros and cons to each of the above. Check the mailing list for some discussions on the topic (see e.g. http://groups.google.com/group/zotonic-users/browse_thread/thread/5f373e46287ddae1/2ce7d18f649f148a).

This cookbook uses the authbind approach. It's simple, works for both HTTP & HTTPS, efficient and prevents problems with duplicate search engine entries. It won't however work for ipv6 addresses as noted above.

Instructions (authbind)

Note: Instructions below assume site is named 'mysite' and zotonic is installed in ~zotonic/zotonic. Replace as appropriate.

  1. Install authbind:

    zotonic:~$ sudo apt-get install authbind 
    
  2. Configure authbind to allow zotonic user to access port 80

    zotonic:~$ sudo touch /etc/authbind/byport/80
    zotonic:~$ sudo chown zotonic /etc/authbind/byport/80
    zotonic:~$ sudo chmod 500 /etc/authbind/byport/80
    
  3. Set up the environment.

    You need to set the IP address. Zotonic defaults to 'any', which will also bind to any ipv6 addresses available. However authbind doesn't work with ipv6 and so will cause zotonic to crash on startup.

    Add the following entries to ~zotonic/.profile (NOTE: ~zotonic/.zotonic_defaults does not appear to work) then save file & exit:

    export ZOTONIC_PORT=80
    export ZOTONIC_PORT_SSL=443
    public_interface=eth0
    export ZOTONIC_IP=`/sbin/ifconfig $public_interface | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`
    export ERL="authbind --deep erl"
    

    where eth0 is the name of the Ethernet interface that connects to the Internet. For a MediaTemple (ve) host this was venet0:0. You could alternatively set it to lo for localhost-only testing or to a LAN-only interface (say eth1) for a multi-interface server you are using Zotonic to host an intranet site with.

  4. Source the file to update the environment:

    zotonic:~$ . ~/.profile
    
  5. Delete the zotonic config file (this will be re-generated automatically when zotonic next starts up)

    zotonic:~$ rm ~zotonic/zotonic/priv/config
    
  6. Set the port for your site. Edit the hostname entry in ~zotonic/priv/sites/yoursite/config to read as follows:

    {hostname, "yoursite:80"}
    
  7. Stop zotonic if already running:

    zotonic:~$ ~/zotonic/bin/zotonic stop
    
  8. Start zotonic:

    zotonic:~$ ~/zotonic/bin/zotonic start
    
  9. Browse to http://yoursite/ and test everything is working OK

Instructions (setcap)

Warning: this is a much broader approach as it grants privileged bind to all Erlang VM processes.  Unless you are the sole user of such a machine this is not a great idea.

  1. From the Root shell: install setcap:

    sudo apt-get install libcap2-bin 
    
  2. From the Root shell: configure setcap to allow Erlang BEAM processes user to bind to ports lower than 1024:

    setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.8.4/bin/beam
    setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.8.4/bin/beam.smp

    The commands for R15B are slightly different (different ERTS version):

    setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.9/bin/beam
    setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.9/bin/beam.smp

    The commands for R15B01 are slightly different again:

    setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.9.1/bin/beam
    setcap 'cap_net_bind_service=+ep' /usr/lib/erlang/erts-5.9.1/bin/beam.smp

    WARNING: during package upgrades Erlang may be upgraded and your site will seem to be broken. Just make sure to check the ERTS version and rerun these setcaps for the new version.

For more granular control, you could create an Erlang release that only the Zotonic User can access.  Once the release is created setcap could be applied to the beam and beam.smp within that release only.  Once I review Erlang and OTP in Action I intend to provide more detailed instructions on that here.

Instructions (iptables)

If authbind and setcap will not work for you iptables is another alternative.  Firewall prerouting can be enabled as follows to forward communication on port 80 to port 8000 and port 443 to port 8443:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8000
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to 8443

Troubleshooting

There are no troubleshooting steps available for this guide.  Please provide any you have learned in the comments below or on the Zotonic Users Group.

This page is part of the Zotonic documentation, which is licensed under the Apache License 2.0.