My goal is to provide a secure email service from a new Ubuntu 16.04 server. In order to do this, I want to set up Apache2 with nginx running as its reverse proxy.
My immediate problem is that Apache fails to start, claiming that there is no SSL certificate assigned (see output from Terminal at the end of this question), even though I am not (yet) attempting to use HTTPS.
My questions:
- If Apache is running on a local port, is it not enough that nginx knows about any SSL certificates?
- What do I need to do to get Apache to start listening on at a local address?
Here is my understanding of what I need to do. I would be grateful if you could point out where my understanding is mistaken.
- Install nginx and Apache2
- Create a nginx server block to:
- Listen on ports 80 (and 443)
- (Redirect traffic from port 80 to port 443)
- (Deal with an SSL certification)
- Forward any requests for a PHP file to Apache at 127.0.0.1:8080
- Set up Apache to:
- Listen only on port 8080, not on port 443
- Remain ignorant of any SSL certification
I like to deal with one problem at a time, so I am currently leaving aside the question of SSL certificates and attempting to get Apache running with nginx as its reverse proxy on port 80 only.
Here are the configuration files that I have in place:
nginx
$ sudo nano /etc/nginx/sites-available/webmail
server {
listen 80;
root /var/www/webmail/web;
index index.php index.html index.htm;
server_name webmail.mydomain.com;
# Look for...
# * the exact path
# * a default (index.*) file, considering the path to be a directory
# ... and if that fails:
# * get the index.php script at the root to deal with the request
location / {
try_files $uri $uri/ /index.php;
}
# If the chosen path leads to a PHP fie:
# * forward the request to Apache running at 127.0.0.1:8080
# * after having modified certain headers
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
# If there are any Apache HT files in the chosen directory
# ignore any direct requests for them
location ~ /\.ht {
deny all;
}
}
Apache2
$ sudo nano /etc/apache2/sites-available/webmail.conf
<VirtualHost 127.0.0.1:8080>
ServerName webmail.mydomain.com
ServerAdmin [email protected]
DocumentRoot /var/www/webmail/web
<Directory "/var/www/webmail/web">
Options FollowSymLinks
AllowOverride All
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Apache2 ports
$ sudo nano /etc/apache2/ports.conf
Listen 127.0.0.1:8080
#<IfModule ssl_module>
# Listen 443
#</IfModule>
#<IfModule mod_gnutls.c>
# Listen 443
#</IfModule>
Note that I am explicitly not asking Apache to listen on port 443. Is there another place in some other config file that is telling Apache to listen on port 443?
Here are my placeholder PHP and HTML files, in their expected places:
index.php
$ sudo nano /var/www/webmail/web/index.php
<?php
echo "PHP from /var/www/webmail/web/index.php\n";
?>
index.html
$ sudo nano /var/www/webmail/web/index.html
<html>
HTML from /var/www/webmail/web/index.html
</html>
In the browser, a request to http://webmail.mydomain.com/index.html succeeds as expected, but a request to http://webmail.mydomain.com/index.php results in the file being downloaded, not executed.
Here's what happens when I try to start Apache2:
$ sudo /etc/init.d/apache2 restart
[ ok ] Restarting apache2 (via systemctl): apache2.service.
$ sudo service apache2 status
* apache2.service - LSB: Apache2 web server
Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
Drop-In: /lib/systemd/system/apache2.service.d
`-apache2-systemd.conf
Active: inactive (dead) since <Time>; 3s ago
Docs: man:systemd-sysv-generator(8)
Process: 16059 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS)
Process: 16043 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCESS)
systemd[1]: Starting LSB: Apache2 web server...
apache2[16043]: * Starting Apache httpd web server apache2
apache2[16043]: Action 'start' failed.
apache2[16043]: The Apache error log may have more information.
apache2[16043]: *
apache2[16059]: * Stopping Apache httpd web server apache2
apache2[16059]: *
systemd[1]: Started LSB: Apache2 web server.
Here's the contents of the error.log:
$ sudo nano /var/log/apache2/error.log
[ssl:emerg] [pid 15943] AH02572: Failed to configure at least one certificate and key for myhostname.hostingservice.com:443
[ssl:emerg] [pid 15943] SSL Library Error: error:140A80B1:SSL routines:SSL_CTX_check_private_key:no certificate assigned
[ssl:emerg] [pid 15943] AH02311: Fatal error initialising mod_ssl, exiting. See /var/log/apache2/error.log for more information
(This is in var/log/apache2/error.log, and there is no more information.)
What have I been missing?
NOTE: The primary purpose of this server is to deliver a Meteor app. I have chosen to do this using Phusion Passenger and Nginx. In addition to the email service, Apache will also be used to deliver a WordPress site.
I have got it working now. I had neglected to remove
/etc/apache2/sites-disabled/default-ssl.conf
, so Apache was trying to run a secure site that wasn't needed.I subsequently used
sudo certbot --nginx
to obtain a certificate for Nginx, and now everything is working securely.