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
- zotonic >=0.7 installed
- Tested on ubuntu 10.04 Server & linux mint 10. Should work on other debian-based distros.
- 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.
Install authbind:
zotonic:~$ sudo apt-get install authbind
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
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.
Source the file to update the environment:
zotonic:~$ . ~/.profile
Delete the zotonic config file (this will be re-generated automatically when zotonic next starts up)
zotonic:~$ rm ~zotonic/zotonic/priv/config
Set the port for your site. Edit the hostname entry in ~zotonic/priv/sites/yoursite/config to read as follows:
{hostname, "yoursite:80"}Stop zotonic if already running:
zotonic:~$ ~/zotonic/bin/zotonic stop
Start zotonic:
zotonic:~$ ~/zotonic/bin/zotonic start
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.
From the Root shell: install setcap:
sudo apt-get install libcap2-bin
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.