This covers the setup of h2o, PHP, phpPgAdmin, and PostfixAdmin.
I first started using h2o because I wanted something that supported HTTP/2
(shortly after the standard was approved) and neither nginx nor apache offered
anything that was not “development”. I very much like the simplicity of its
configuration, light resource footprint, and responsive behavior.
Documentation for h2o.
Getting this setup for serving up our mail related sites is really easy. We
need to add 2 bits to the h2o.conf file (if you want to read about security for
h2o, Calomel h2o has a great writeup). The config file is yaml, and
sensitive to spacing. If you get errors on startup, don’t forget to check the
spacing of things.
This takes care of not only handing all the php(1) files to php-fpm, but
also defining index.php as an optional index file.
The second section is the paths we want to make available to run our
applications. There are several: phpPgAdmin, PostfixAdmin, policyd, and
I’ve defined 2 “hosts” here. The first accepts traffic on port 80, sends back
a 301 redirect to the same host, but port 443 (which is SSL encrypted). You
might be wondering why not include the HSTS header with the redirect, so the
browser would know to only use HTTPS. The browser won’t trust an HSTS header
unless its sent over HTTP. Otherwise it could be altered in transit. The
section looks like this:
I’ve set the minimum version of TLS to be 1.2. As long as you have a
relatively recently version of a popular browser, you should be fine with
this. I’ve also restricted the ciphers to what can be found on Mozilla’s
Security/Server Side TLS under the moniker ‘modern’.
Now we need to create the .htpasswd file in the policyd directory. If you have
a system with apache, you can use the included utility. If you are just
testing things, you can use this
web based htpasswd generator.
Now we can create a php.ini file. In /usr/local/etc/, copy the production one.
cp php.ini-production php.ini
Now edit the php.ini and set the date/timezone. If you run lots of servers,
I’d suggest UTC. Also, here are some security best practices:
In case you’re wondering, the config below is HTTP/2 compliant and modern
browsers will access the site via HTTP/2.
# vi: ft=yaml# to find out the configuration commands, run: h2o --helpuser:wwwpid-file:/var/run/h2o.pidaccess-log:/var/log/h2o/h2o-access.logerror-log:/var/log/h2o/h2o-error.log# php-fpmfile.custom-handler:extension:.phpfastcgi.connect:host:127.0.0.1port:9000type:tcp# Directory Indexfile.index:['index.php','index.html']file.dirlisting:off# per-host configurationhosts:"mx.cryptomonkeys.com:80":listen:port:80paths:/:redirect:status:301url:https://mx.cryptomonkeys.com/"mx.cryptomonkeys.com:443":header.add:"strict-transport-security: max-age=31556926; preload"listen:port:443ssl:certificate-file:/usr/local/etc/ssl/server.crtkey-file:/usr/local/etc/ssl/server.keydh-file:/usr/local/etc/ssl/dh2048.pemcipher-preference:servercipher-suite:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSKminimum-version:TLSv1.2paths:"/ppa":file.dir:"/usr/local/www/phpPgAdmin""/pfa":file.dir:"/usr/local/www/postfixadmin""/webmail":file.dir:"/usr/local/www/roundcube""/policyd":file.dir:"/usr/local/www/policyd"
This component is optional. If you are comfortable using psql(1) to manipulate
the databases, there is no need to install this. If you choose to skip it,
don’t forget to remove the appropriate lines from the h2o.conf and restart h2o.
Now you should be able to point your browser at your webserver
(https://my-ip/ppa/), and get something that looks similar to this:
PostfixAdmin is the easy way for people to control virtual users and domains.
Privlidges are assignable by domain so you can give somebody free reign over
their own domain(s) if you wish. Documentation for
PostfixAdmin defaults the install to /usr/local/www/postfixadmin. We need to
edit the config.inc.php file first. I’ve made the following changes (to
Once you have these bits set, you should be able to point your browser at
https://my-ip/pfa/setup.php and get something that looks similar to this:
Come up with a “setup password” and admin credentials. Then you can re-point
your browser at https://my-ip/pfa/, and get something that looks similar to
You should be able to login to PostfixAdmin and create domains, users, and
aliases. They take effect immediately.
NOTE: If you wish to convert from MySQL to PostgreSQL (insert plenty of
comments about the one true database), you will need to do a little dirty work.
Its not terribly complicated, but it is a manual process.
Start by dumping the postfix database from mysql(1).