You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> * Replace `example.com` with `server_name` of the `server` you want to configure, and `http` with `https` if necessary.
136
-
>
136
+
>
137
137
> * The combination of the domain (or an IP) and port must correspond to the nginx `server_name` and `listen` directive (in this example, port `80` is used because it is the default for HTTP).
138
138
139
139
You should get the output similar to this, with the HTTP status `200`:
@@ -168,7 +168,7 @@ You need to add this line to the appropriate `location` context in your `server`
168
168
deny 10.0.0.5;
169
169
```
170
170
171
-
> Replace `10.0.0.5` with your own public IP.
171
+
> Replace `10.0.0.5` with your own public IP.
172
172
173
173
The complete configuration may look like this:
174
174
@@ -297,9 +297,9 @@ sudo systemctl reload nginx
297
297
<summary><b>Attention!</b></summary>
298
298
299
299
1. If you have a configuration like this, requests to `example.com/admin/index.php` will **not** be protected:
300
-
300
+
301
301
> The request is handled with the `location ~ \.php$` context. This means that the allow and deny directives of `location /admin` are **not** used.
302
-
302
+
303
303
```nginx
304
304
server {
305
305
listen 80;
@@ -318,23 +318,23 @@ sudo systemctl reload nginx
318
318
}
319
319
}
320
320
```
321
-
321
+
322
322
> *`location /` and `location /admin` are "prefix locations"
323
323
> *`location ~ \.php$` is a "regular expression location"
324
-
324
+
325
325
In the example request `example.com/admin/index.php`:
326
-
326
+
327
327
* The path `/admin` matches with the "**prefix location**" `location /admin`.
328
328
* The file `index.php` matches with the "**regular expression location**" `location ~ \.php$`.
329
-
329
+
330
330
Nginx remembers the longest **prefix location** that matches the request, in this example that's `location/admin`. However, it will only use the **prefix location** to process the request if no **regular expression location** matches the request. In this example, the regular expression location `location ~ \.php$` matches the request and is used.
331
-
331
+
332
332
**Regular expression locations** are marked with a tilde `~` or `~*`. Starting from the top of the `server` block, nginx first checks every **prefix location** inside out. The first matching regular expression location that nginx can find is automatically used.
333
-
333
+
334
334
Hence, the regular expression `location` must be defined separately for the protected prefix `location` as show below.
335
-
335
+
336
336
2. If you edit the configuration from above like this, requests to `example.com/admin/index.php` will be protected:
337
-
337
+
338
338
> The request is handled with the first **regular expression locations** that matches the request. In this configuration, that's the `location ~ \.php$` context within the `location /admin` context. This means that the allow and deny directives of `location /admin`**are used**.
339
339
340
340
```nginx
@@ -360,17 +360,17 @@ sudo systemctl reload nginx
360
360
}
361
361
}
362
362
```
363
-
363
+
364
364
3. If you don't like duplication, you can put the common parts into a file and refer to this file via an `include` directive. In this example, the file `/etc/nginx/php.conf` can be created with these directives:
365
-
365
+
366
366
```nginx
367
367
try_files $fastcgi_script_name =404;
368
368
fastcgi_pass unix:/run/php/php-fpm.sock;
369
369
include fastcgi.conf;
370
370
```
371
-
371
+
372
372
Now, it can be included:
373
-
373
+
374
374
```nginx
375
375
server {
376
376
listen 80;
@@ -455,75 +455,75 @@ and you can show the message to the blocked client. The message can contain vari
455
455
First of all, you need to install the nginx dynamic module `geoip2` which adds support for the IP databases with geographical information. The database will be queried to determine the country of the user by their IP. This information in turn will be used to allow or block access.
By default, at the beginning of the file `/etc/nginx/nginx.conf` and outside of any curly brackets, you must have the uncommented line:
466
-
466
+
467
467
```nginx
468
468
include /etc/nginx/modules-enabled/*.conf;
469
469
```
470
-
470
+
471
471
If it's not the case, you need to add or uncomment it.
472
-
472
+
473
473
Alternatively, you can load only `geoip2` module like this:
474
-
474
+
475
475
```nginx
476
476
load_module modules/ngx_http_geoip2_module.so;
477
477
```
478
-
478
+
479
479
- Reload the nginx configuration:
480
-
480
+
481
481
```bash
482
482
sudo systemctl reload nginx
483
483
```
484
484
485
485
Now you only have the `geoip2` module, this is not enough to start enabling restrictions.
486
486
487
-
You need to download the `geoip2` compatible IP database that can be used to check the country of a user.
487
+
You need to download the `geoip2` compatible IP database that can be used to check the country of a user.
488
488
489
489
- Install the required package:
490
-
491
-
490
+
491
+
492
492
```bash
493
493
cd /etc/nginx && sudo curl --fail -LO https://github.com/P3TERX/GeoLite.mmdb/releases/latest/download/GeoLite2-Country.mmdb
494
494
```
495
-
495
+
496
496
Alternatively you can [create an account](https://www.maxmind.com/en/geolite2/signup?lang=en) on the MaxMind website and download the GeoLite2 Country database from there:
497
-
497
+
498
498
1. Open the [registration form](https://www.maxmind.com/en/geolite2/signup?lang=en) in your browser and fill it in.
499
499
2. You will receive an email with the link to create your password.
500
500
3.[Log in](https://www.maxmind.com/en/account/login) with your email and password.
501
501
4. Go to `Account / Manage License Keys` and create a new license key. Copy your license key and save it somewhere.
502
502
5. Now you can download the GeoLite2 Country database by running this command:
503
-
503
+
504
504
```bash
505
505
cd /etc/nginx && sudo curl --fail -o GeoLite2-Country.tar.gz "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_LICENSE_KEY&suffix=tar.gz"&& sudo tar --strip-components=1 -xzf GeoLite2-Country.tar.gz --wildcards "*.mmdb"&& sudo rm GeoLite2-Country.tar.gz
506
506
```
507
507
> Replace `YOUR_LICENSE_KEY` with your license key. The database is saved to the file `/etc/nginx/GeoLite2-Country.mmdb`.
508
-
508
+
509
509
- Edit the nginx configuration
510
-
510
+
511
511
Now you need to edit your nginx configuration to add the `geoip2` directive which loads the database into nginx. After the database is loaded, it can be used to block or allow access.
512
512
The complete configuration may look like this:
513
-
513
+
514
514
>`0 = allow` and `1 = deny`
515
515
516
516
```nginx
517
517
geoip2 /etc/nginx/GeoLite2-Country.mmdb {
518
518
$user_country country iso_code;
519
519
}
520
-
520
+
521
521
map $user_country$not_allowed {
522
522
CA 1;
523
523
US 1;
524
524
default 0;
525
525
}
526
-
526
+
527
527
server {
528
528
listen 80;
529
529
server_name example.com;
@@ -534,16 +534,16 @@ You need to download the `geoip2` compatible IP database that can be used to che
534
534
}
535
535
}
536
536
```
537
-
537
+
538
538
*`geoip2` directive is used to specify the path to an IP database and to define variables.
539
539
In the example above, the variable `$user_country` is defined.
540
540
When the request is processed by nginx, this variable is set to the user country's two-letter code.
541
-
541
+
542
542
* `map` directive is used to create the boolean variable `$not_allowed`. Its value is chosen according to the `$user_country` variable defined in the `geoip2` block.
543
543
In this example configuration, the users from United States and Canada are blocked, users from other countries are allowed. The two-letter country codes which can be used inside the `map` are listed [on this Wikipedia page](https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes).
544
-
544
+
545
545
* Finally, the `$not_allowed` variable is used inside the `if` statement to block or allow a request.
546
-
546
+
547
547
You can find more information about the `geoip2` module on its [GitHub page](https://github.com/leev/ngx_http_geoip2_module).
548
548
549
549
## Step 5 - Password-based authentication
@@ -552,21 +552,21 @@ You can restrict access by only allowing access to users with a password. This i
552
552
553
553
> You can use [this tutorial](https://community.hetzner.com/tutorials/add-ssl-certificate-with-lets-encrypt-to-nginx-on-ubuntu-20-04) to setup HTTPS.
554
554
> The configuration you will end up with will be similar to this:
555
-
>
555
+
>
556
556
> ```nginx
557
557
> server {
558
558
> server_name example.com;
559
559
> location / {
560
560
> }
561
-
>
561
+
>
562
562
> listen 443 ssl; # managed by Certbot
563
563
> ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
564
564
> ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
565
565
> include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
566
566
> ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
567
567
> }
568
568
> ```
569
-
>
569
+
>
570
570
> After you have configured HTTPS, you can setup the password-based authentication.
571
571
572
572
First of all, you need to create a special file where all usernames and corresponding passwords are stored.
@@ -576,22 +576,32 @@ You can create it like this:
576
576
sudo touch /etc/nginx/users
577
577
```
578
578
579
-
You can use this command to add users:
579
+
You can use this command to add users: <a id="create_user"></a>
580
580
581
581
* Follow the prompts. If you made a mistake, you can cancel the command by pressing `Ctrl + C`.
582
582
583
583
* Note that this command uses `sudo` and may ask for your password, this is not the password for the new user.
print("Username or password is empty. Try again!", file=sys.stderr) if user == "" or passwd == ""else print(user + ":" + passwd)' | sudo tee -a /etc/nginx/users
586
+
while true; do
587
+
read -r -p "Username: " ngxuser
588
+
if [[ -z "$ngxuser" ]]; then
589
+
echo "Username is empty. Try again!"
590
+
continue
591
+
fi
592
+
ngxpass="$(openssl passwd -6)"
593
+
if (( $? != 0 )); then
594
+
echo "Try again!"
595
+
else
596
+
break
597
+
fi
598
+
done; echo "$ngxuser:$ngxpass" | sudo tee -a /etc/nginx/users
589
599
```
590
600
591
601
Above command will add the user to the `/etc/nginx/users` file, and additionally output the username and hash of the password to your terminal separated by a colon `:`.
592
602
The password itself is not stored on the server.
593
603
594
-
You can add more users to `/etc/nginx/users` by repeating the same `python3` command above.
604
+
You can add more users to `/etc/nginx/users` by repeating the same command above.
595
605
You can manually edit `/etc/nginx/users` to remove users. Each user is on a separate line.
596
606
597
607
The special file with users is created and you can now modify your `server` block.
@@ -642,14 +652,14 @@ You can test the new configuration with `curl`:
642
652
643
653
* With username and password:
644
654
645
-
Replace `user` with your username, `password` with your password created using the `python3` command above, and `example.com` with your domain.
655
+
Replace `user` with your username, `password` with your password created using the [command above](#create_user), and `example.com` with your domain.
This time you should get HTTP status `200` and the requested content. Response headers will look like this:
652
-
662
+
653
663
```
654
664
< HTTP/1.1 200 OK
655
665
< Server: nginx
@@ -667,7 +677,7 @@ You can test the new configuration with `curl`:
667
677
**Restricting access to a single URL**
668
678
669
679
- You can restrict access to a single URL by adding the `auth_basic` and `auth_basic_user_file` directives directly to a `location` context instead of its parent-context `server`. For example:
670
-
680
+
671
681
```nginx
672
682
server {
673
683
server_name example.com;
@@ -677,29 +687,29 @@ You can test the new configuration with `curl`:
677
687
auth_basic "Protected area!";
678
688
auth_basic_user_file /etc/nginx/users;
679
689
}
680
-
690
+
681
691
listen 443 ssl; # managed by Certbot
682
692
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
683
693
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
684
694
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
685
695
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
686
696
}
687
697
```
688
-
698
+
689
699
Here, `location /admin` is protected by password-based authentication.
690
700
691
701
-------------
692
702
693
703
**Logging of wrong access details**
694
704
695
705
- If someone used the wrong password, it will be logged to the `/var/log/nginx/error.log` file like this:
0 commit comments