Table of Contents | ||||
---|---|---|---|---|
|
...
Code Block |
---|
proxy_intercept_errors on; error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 /custom_error.html; location = /custom_error.html { internal; root /usr/share/nginx/html; } |
Using letsencrypt to provide certificates
...
Including a redirect to connections to port 80
Leaving port 80 open and including a redirect is widely recommended (including, for example, by Let’s Encrypt: https://letsencrypt.org/docs/allow-port-80/https://letsencrypt.org/docs/allow-port-80/https://letsencrypt.org/ to provide secure connections over HTTPS. Let’s Encrypt is a well known Certificate Authority (CA) that is free to use. Check with your organisation on standards for certificates. You may need to use a different public CA, or an internal CA. Using CAs aside from Let’s Encrypt is well documented on the web. In particular, most public CAs will docuemnt how their certificates can be installed into NGINX.
If you do not use Certbot, skip the section Install certificate using Certbot below, and follow instructions appropriate for your CA.
Installing with apt
The instructions below are based on installation on a Debian-based distribution of Linux, and use the apt command. If you are installing on a RedHat-based distribution of Linux, the equivalent yum commands for NGINX installation are well documented on the web.
Single server, single PhixFlow webapp
The /docs/allow-port-80/. In particular, this allows Let’s Encypt to automatically renew the certificate using the default HTTP-01 challenge.
Hide version number
In this installation, we hide the version number on the default NGINX page. This is a useful secuity measure. Because errors are already redirected to a standard error page (see above), in this installation you are unlikely to see this in a browser. But this can be viewed using a client such a curl that does not apply the port 80 redirect, or by querying for the header information for the service.
Using letsencrypt to provide certificates
The method below uses https://certbot.eff.org/ to issue and install certificates from https://letsencrypt.org/ to provide secure connections over HTTPS. Let’s Encrypt is a well known Certificate Authority (CA) that is free to use. Check with your organisation on standards for certificates. You may need to use a different public CA, or an internal CA. Using CAs aside from Let’s Encrypt is well documented on the web. In particular, most public CAs will docuemnt how their certificates can be installed into NGINX.
If you do not use Certbot, skip the section Install certificate using Certbot below, and follow instructions appropriate for your CA.
Installing with apt
The instructions below are based on installation on a Debian-based distribution of Linux, and use the apt command. If you are installing on a RedHat-based distribution of Linux, the equivalent yum commands for NGINX installation are well documented on the web.
Single server, single PhixFlow webapp
The following instructions assume that NGINX is installed on the same server as PhixFlow itself (i.e. the same server as the tomcat installation), and with a single installation of PhixFlow (a “webapp”). If you have multiple webapps on a single server, multiple webapps across several several servers, or a single webapp on a different server from the reverse proxy, see Multiple PhixFlow webapps or multiple servers below.
...
Set up a domain record
Choose a domain, e.g. phixflow.mycompany.com, and set up an A record on your DNS to point this domain at the public IP address of the server that you are installing NGINX on.
Install NGINX
Install NGINX from the repository
...
Run sudo apt install curl gnupg2 ca-certificates lsb-release
to install the prerequisites.
Run the following to set up the repository for mainline packages:
...
. Instructions for various linux distributions can be found here: http://nginx.org/
...
The example given here is taken from those instructions, and is for installation of NGINX mainline on Ubuntu.
Install prerequisites:
Code Block | ||
---|---|---|
| ||
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring |
Import the official NGINX signing key so that the package can be verified:
Code Block |
---|
curl https://nginx.org/keys/nginx_signing.key | |
...
Run sudo apt-key fingerprint ABF5BD827BD9BF62
to verify you have the proper key - the output should contain the full fingerprint: 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
.
...
Run sudo apt update
and sudo apt install nginx
.
...
Note |
---|
These steps are a work in progress |
Open the server to port 80 (HTTP), both in GCP firewalls and ufw on the server.
Follow the instructions here up to Step 7: https://certbot.eff.org/instructions?ws=nginx&os=ubuntubionic. In Step 7, run the first command: sudo certbot --nginx
- the final stage of this (installing the certificate into NGINX) will fail. Continuing with the instructions here will install the certificate manually.
Configure NGINX
Run
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
to create a default copy of the default configuration.Create a file
/etc/nginx/conf.d/phixflow.conf
(e.g. withsudo nano /etc/nginx/conf.d/phixflow.conf
) and paste in the following, replacing[subdomain]
with the appropriate subdomain of the server:Code Block server { listen 443 ssl; listen [::]:443 ssl ipv6only=on; server_name [subdomain].phixflow.com; proxy_intercept_errors on; error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 /custom_error.html; location = /custom_error.html { internal; root /usr/share/nginx/html; } location / { proxy_pass http://127.0.0.1:8080; } ssl_certificate /etc/letsencrypt/live/[subdomain].phixflow.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/[subdomain].phixflow.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; client_max_body_size 40M; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; }
Create a custom error page
Create a file
/usr/share/nginx/html/custom_error.html
(e.g. withsudo nano /usr/share/nginx/html/custom_error.html
) and enter the following contents:Code Block language html <!doctype html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="IE=11" /> <title>PhixFlow Error</title> </head> <body> <div class="access-error" style="font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 24px; text-align: center; position:absolute; top:300px; width:100%; "> An unexpected error has occurred opening PhixFlow, please contact the support desk. </div> </body> </html>
Restart NGINX:
Code Block sudo nginx -s reload sudo service nginx stop sudo service nginx start
You may need to reboot the server as well in order for NGINX to restart successfully.
Run
netstat -tln
to check the server is listening on port 443 rather than 80.Check the PhixFlow application loads in the browser. Check the security settings in the browser console.
Run
nginx -V
to check the version.
Configure SSL cipher restriction
This is based on recommendations given at: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations. Note that there is a scheduled audit to review these on a regular basis and update our build instructions to continue to comply with the recommendations.
Open the file at /etc/letsencrypt/options-ssl-nginx.conf
. It should look similar to the following:
Code Block |
---|
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"; |
Edit the ssl_protocols
parameter to be:
Code Block |
---|
ssl_protocols TLSv1.3; |
Edit the ssl_ciphers
parameter to be:
Code Block |
---|
ssl_ciphers "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"; |
Close and save the file.
Run the following to reload the NGINX configuration:
Code Block |
---|
sudo nginx -s reload |
Restart the NGINX service:
Code Block |
---|
sudo service nginx restart |
...
A single reverse proxy can handle connections to different webapps (i.e. installations of PhixFlow), whether these are hosted on a single server, or across several servers. See *** for common network configuration for PhixFlow installation. However, whichever configruation you choose, the configuration is the same: you need an IP address and a webapp name to define each PhixFlow installation.
Note that, since NGINX is acting as the the point of SSL termination, that if you specify a PhixFlow installation at an IP address, you must make sure that the route from the reverse proxy to the PhixFlow installation is secure. The suggested configurations in *** will provide this since traffic is sent within a private network.
In the following example, a single reverse proxy on a dedicated server is handling incoming connections to:
...
System name
...
Server IP address
...
Webapp name
...
Production
...
10.154.0.12
...
prod, installed at: /opt/tomcat/webapps/prod
...
UAT
...
10.154.0.13
...
uat, installed at: /opt/tomcat/webapps/uat
...
Dev 1
...
10.154.0.14
...
dev1, installed at /opt/tomcat/webapps/dev1
...
Dev 2
...
10.154.0.14
...
dev2, installed at /opt/tomcat/webapps/dev2
To support connections to all these systems replace the directive
Code Block |
---|
location / {
proxy_pass http://127.0.0.1:8080;
} |
in the example phixflow.conf
file above with:
Code Block |
---|
location /prod {
proxy_pass http://10.154.0.12:8080;
}
location /uat {
proxy_pass http://10.154.0.13:8080;
}
location /dev1 {
proxy_pass http://10.154.0.14:8080;
}
location /dev2 {
proxy_pass http://10.154.0.14:8080;
} |
Switching NGINX from stable branch to mainline
Info |
---|
This section should no longer be used, but has been retained for reference |
...
Run sudo apt remove nginx
to remove the current installation of NGINX while preserving the configuration files.
...
Run sudo apt install curl gnupg2 ca-certificates lsb-release
to install the prerequisites.
...
Run the following to set up the repository for mainline packages:
Code Block |
---|
echo "deb http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list |
...
Run curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
to import an official NGINX signing key so apt can verify the package's authenticity.
...
Run sudo apt-key fingerprint ABF5BD827BD9BF62
to verify you have the proper key.
...
The output should contain the full fingerprint 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
.
...
Run sudo apt update
and sudo apt install nginx
.
...
Run sudo rm /etc/nginx/conf.d/default.conf
to remove the default configuration.
...
Run sudo vim /etc/nginx/nginx.conf
and add include /etc/nginx/sites-enabled/*;
below the line include /etc/nginx/conf.d/*.conf;
.
...
Run sudo nginx -s reload
.
...
Run sudo service nginx stop
.
...
Run sudo service nginx start
.
...
Run netstat -tln
to check the server is listening on port 443 rather than 80.
...
Check the PhixFlow application loads in the browser. Check the security settings in the browser console.
...
gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null |
Verify the downloaded file:
Code Block |
---|
gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg |
The output should contain the full fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
as follows:
Code Block |
---|
pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid nginx signing key <signing-key@nginx.com> |
Add the mainline packages to your repository list:
Code Block |
---|
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list |
Set up repository pinning:
Code Block |
---|
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx |
Install NGINX:
Code Block |
---|
sudo apt update
sudo apt install nginx |
Anchor | ||||
---|---|---|---|---|
|
Open the server to port 80 (HTTP), both in GCP firewalls and ufw on the server.
The following instructions are based on the recommended installation of certbot with snap: https://certbot.eff.org/instructions?ws=nginx&os=ubuntubionic. This link also includes alternative instructions for installing certbot if you don’t want to use snap.
These instructions also assume that snap is installed on your system. If it is not, you can following instructions here: https://snapcraft.io/docs/installing-snapd
Ensure that snapd is up to date:
Code Block |
---|
sudo snap install core; sudo snap refresh core |
Install certbot
Code Block |
---|
sudo snap install --classic certbot |
Link certbot command to make it accessible:
Code Block |
---|
sudo ln -s /snap/bin/certbot /usr/bin/certbot |
Request a certificate:
Code Block |
---|
sudo certbot certonly --nginx |
When the final command runs, it will prompt for several respsonses:
An email address (for urgent renewal and security notices): e.g. security.notifications@mycompany.com
Terms of service: you must agree to these (press Y)
Agreement to share your email address with EFF: you can choose either option, i.e. Y or N
The domain name assigned to this service: e.g. phixflow.mycompany.com
Configure NGINX
Most distributions of NGINX no longer include sites-enabled
and sites-available
directories. This example installation is based on distribution that does not include these directories, and places the configuration file in the /etc/nginx/conf.d directory
. If your installed version of NGINX includes sites-enabled
and sites-available
directories, consult the NGINX documentation for further guidance.
Save a backup of the default configuration file:
Code Block |
---|
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak |
Create configuration file for PhixFlow: open editing on a file /etc/nginx/conf.d/phixflow.conf
(e.g. with sudo nano /etc/nginx/conf.d/phixflow.conf
) and paste in the following, replacing [domin]
with your domain, e.g. phixflow.mycompany.com:
Code Block |
---|
server {
listen 443 ssl;
listen [::]:443 ssl ipv6only=on;
server_name [domain];
proxy_intercept_errors on;
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 /custom_error.html;
location = /custom_error.html {
internal;
root /usr/share/nginx/html;
}
location / {
proxy_pass http://127.0.0.1:8080;
}
ssl_certificate /etc/letsencrypt/live/[domain]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[domain]/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 40M;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
} |
Create a custom error page: open editing on a file /usr/share/nginx/html/custom_error.html
(e.g. with sudo nano /usr/share/nginx/html/custom_error.html
) and paste in the following:
Code Block |
---|
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=11" />
<title>PhixFlow Error</title>
</head>
<body>
<div class="access-error" style="font-family: Verdana, Helvetica, Arial, sans-serif; font-size: 24px; text-align: center; position:absolute; top:300px; width:100%; ">
An unexpected error has occurred opening PhixFlow, please contact the support desk.
</div>
</body>
</html> |
Hide version number:
Edit the file /etc/nginx/nginx.conf
, and in the http context add the line server_tokens off;
. This will result in a file that looks similar to:
...
Restart NGINX:
Code Block |
---|
sudo nginx -s reload
sudo service nginx stop
sudo service nginx start |
Notes:
You may need to reboot the server as well in order for NGINX to restart successfully.
Run
netstat -tln
to check the server is listening on port 443 and port 80Check the PhixFlow application loads in the browser. Check the security settings in the browser console.
Configure SSL cipher restriction
This is based on recommendations given at: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations.
Open the file at /etc/letsencrypt/options-ssl-nginx.conf
. It should look similar to the following:
Code Block |
---|
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; |
Edit the ssl_protocols
parameter to be:
Code Block |
---|
ssl_protocols TLSv1.3; |
Edit the ssl_ciphers
parameter to be:
Code Block |
---|
ssl_ciphers "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"; |
Close and save the file.
Run the following to reload the NGINX configuration:
Code Block |
---|
sudo nginx -s reload |
Restart the NGINX service:
Code Block |
---|
sudo service nginx restart |
Anchor | ||||
---|---|---|---|---|
|
A single reverse proxy can handle connections to different webapps (i.e. installations of PhixFlow), whether these are hosted on a single server, or across several servers. See *** for common network configuration for PhixFlow installation. However, whichever configruation you choose, the configuration is the same: you need an IP address and a webapp name to define each PhixFlow installation.
Note that, since NGINX is acting as the the point of SSL termination, that if you specify a PhixFlow installation at an IP address, you must make sure that the route from the reverse proxy to the PhixFlow installation is secure. The suggested configurations in *** will provide this since traffic is sent within a private network.
In the following example, a single reverse proxy on a dedicated server is handling incoming connections to:
System name | Server IP address | Webapp name |
---|---|---|
Production |
| prod, installed at: |
UAT |
| uat, installed at: |
Dev 1 |
| dev1, installed at |
Dev 2 |
| dev2, installed at |
To support connections to all these systems replace the directive
Code Block |
---|
location / {
proxy_pass http://127.0.0.1:8080;
} |
in the example phixflow.conf
file above with:
Code Block |
---|
location /prod {
proxy_pass http://10.154.0.12:8080;
}
location /uat {
proxy_pass http://10.154.0.13:8080;
}
location /dev1 {
proxy_pass http://10.154.0.14:8080;
}
location /dev2 {
proxy_pass http://10.154.0.14:8080;
} |