NGINX is one of the most popular web servers in the world. Not only is NGINX a fast and reliable static web server, it is also used by a ton of developers as a reverse-proxy that sits in front of their APIs. In this tutorial we will take a look at the NGINX Official Docker Image and how to use it. Installing as a Linux package. For Linux, njs modules packages can be used: nginx-module-njs — njs dynamic modules. Nginx-module-njs-dbg — debug symbols for the nginx-module-njs package. After package installation, njs dynamic modules need to be loaded with the loadmodule directive: loadmodule modules/ngxhttpjsmodule.so. NGINX Ingress controller can be installed via Helm using the chart from the project repository.To install the chart with the release name ingress-nginx: Download Nginx For Mac Without Homebrew If you are using Helm 2 then specify release name using -name flag.
Step 1: download and install your license key
Before you can install Passenger Enterprise, you need to download and install your license key. This is a regular file that you need to copy to your production server.
Please login to the Passenger Enterprise Customer Area.
Click on the Install button in the Customer Area.
Click on the button to download the license key.
The license key will be downloaded to your local computer. Copy this license key file to your production server, for example using scp
:
Replace adminuser
with the name of an account with administrator privileges or sudo privileges.
Finally, login to your production server and save the file as /etc/passenger-enterprise-license
:
Step 2: obtain your download token
Your download token is needed in order to install Passenger Enterprise. In the Customer Area, find your download token and copy it to your clipboard.
Step 3: install Passenger package
You can install Passenger through Homebrew:
You will be prompted to provide your download token when you install Passenger Enterprise through Homebrew, to avoid this prompt create a file at `~/.passenger-enterprise-download-token` containing only your token.
Not using Homebrew? Please go back to the operating system selection menu and choose 'Other' as operating system.
Step 4: enable the Passenger Nginx module and restart Nginx
Passenger is now installed, but it still needs to be enabled inside Nginx. Run brew info nginx-passenger-enterprise
and follow the instructions in the 'Caveats' section:
When you are done following the instructions, restart Nginx:
Step 5: check installation
After installation, please validate the install by running sudo /usr/local/bin/passenger-config validate-install
. For example:
All checks should pass. If any of the checks do not pass, please follow the suggestions on screen.
Finally, check whether Nginx has started the Passenger core processes. Run sudo /usr/local/bin/passenger-memory-stats
. You should see Nginx processes as well as Passenger processes. For example:
If you do not see any Nginx processes or Passenger processes, then you probably have some kind of installation problem or configuration problem. Please refer to the troubleshooting guide.
When testing changes to your Nginx configuration for your stagingor production (or any other remote) environments, one can encounter problems:
- If the changes are made as part of a CI/CD pipeline, each change requires you to wait for the pipeline to buildbefore testing. This waiting time will typically be minutesrather than seconds
- Making the changes directly to the configuration files on the server means you can test your changes basically straight away. However,
- If you have a load balancer directing traffic to more than one instance, you have to make the same change in several places
- If you have a load balancer and your instances are in a private subnet, SSH-ing into those instances requires setting up a VPN
- Changing files directly on a server is bad practice as there is no record of those changes. What happens if you would like to revert a mistake?
One way around this is to test your Nginx configuration changeslocally (like you would with regular application code).
In this post we will show how to do this.
Prerequisites
- Docker; whilst you could download Nginx directly onto your machine, using Docker means you can easily:
- Install and uninstall Nginx
- Reset your Nginx configuration files
- Run multiple Nginx processes at the same time
- Change the port Nginx runs on
- Change Nginx version…, etc.
Getting started
To run Nginx in a Docker container and serve requests on port 8000 on your machine,
docker run --interactive --tty --publish 8000:80 nginx bash
(if you are on macOS, you might have to start theDocker daemon first by clicking on an icon)
This command also SSHs you into the container.
In the container shell, check Nginx is installed
which nginx
/usr/sbin/nginx
and that it is running
service nginx status
[FAIL] nginx is not running ... failed!
As it is not running, start it
service nginx start; service nginx status
[ ok ] nginx is running.
Make a request to http://localhost:8000
in the browser. You should see the 'Welcome to nginx!'
page.
Similarly, in Python
you should get back the HTML of the page and the responsestatus code.
You should also see the relevant logs in the container shell
172.17.0.1 - - [21/Oct/2019:17:53:21 +0000] 'GET /favicon.ico HTTP/1.1' 404 555 'http://localhost:8000/' 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36' '-'
172.17.0.1 - - [21/Oct/2019:17:54:51 +0000] 'GET / HTTP/1.1' 200 612 '-' 'python-requests/2.18.4' '-'
Changing the “Welcome to nginx” page
To make changes to the Nginx configuration, we will need to editfiles inside the container shell.
By default, there is no text editor inside the containershell.
We will install Vim, but any text editor will do.
Inside the container shell,
apt-get update
apt-get install vim --yes
We can now use our text editor to have a look at the Nginxconfiguration
cd /etc/nginx/conf.d
vi default.conf
You should see the following configuration or similar
As the web server document root is /usr/share/nginx/html
,inside /usr/share/nginx/html
is index.html
.
Change index.html
so that the title and header reads'Bienvenue a nginx!'
instead of 'Welcome to nginx!'
.
To let the changes take effect, restart Nginx
service nginx reload
Nginx Download Mac Version
When you make a request to http://localhost:8000
, you shouldsee the new title and header.
Nginx Mac Install
Changing the Nginx configuration to prevent web cache poisoning
Web cache poisoning is geared towards sending a request that causes a harmful response that then gets saved in the cache and served to other users.
One method of web cache poisoning starts with spoofing the host in the request header.
For example, if your website is written in Django, Django uses the host in the request header when generating its URLs.
Thus if you have a Django URL /my-login
, and the host in therequest header is malicious-hacker.com
(although your site’sdomain is my-site.com
), if Django internally makes requeststo /my-login
, these requests will go tohttp://malicious-hacker.com/my-login
and nothttp://my-site.com/my-login
.
http://malicious-hacker.com/my-login
then sends a harmfulresponse that gets saved in the cache and served to other users.Web cache poisoning complete!
To mitigate this security risk, Django has an ALLOWED_HOSTS
setting.
By setting
Django will only make requests to my-site.com
. If an attackersends a request with host malicious-hacker.com
, it throwsa SuspiciousOperation
error and returns a Bad request
response with status code 400
.
One of the drawbacks of the above is that it usually leads to noisy logging due to bots checking for vulnerabilities in your site.
Assuming your website is served by Nginx, one way aroundthis is to configure Nginx so that any request with a hostin the header not equal to my-site.com
is given a 4xx
error response (ideally, the error code should capture justthis issue as otherwise all you have done is transferredyour noisy logging problem from Django to Nginx).
Let’s now test this workaround locally.
Making a spoof request in Python
The response is exactly the same as before, despite having
server_name localhost;
in our server block in default.conf
and the host in therequest header being abc.com
.
Changing the Nginx configuration
So why did we get a 200
response despitethe host in the Nginx configuration not matching the host sentin the request?
This is because if Nginx finds no matching server blocks,it uses the first server block.
To check this, let’s add
to the end of default.conf
. To make the changes take effect,
service nginx reload
Now, making the same request in Python, we get a responsestatus code of 403
with content
'Your request is forbidden'
However, if we spoof the header with a host different to abc.com
, we will get a 200
again.
Actually, all we have to do is add
to the start of default.conf
.
Now, whenever the host in the header is not equal to localhost
, a 403
is returned.
Although functionally it makes no difference, the conventionis to add default_server
to the block, i.e. to have
Nginx Virtual Machine Download
at the start of default.conf
.
Download Nginx Mac Os
Now your Nginx configuration is setup to prevent web cachepoisoning!