1

It's been a while since I needed ServerFault, I hope someone can help me. I am trying to secure my Laravel (PHP) application running on Amazon Linux with LetsEncrypt free SSL.

Using certbot-auto, I have successfully generated the SSL Certificates like this:

./certbot-auto --debug -v --server https://acme-v01.api.letsencrypt.org/directory certonly -d example.com -d www.example.com

I have also generated dhparam using this command:

openssl dhparam -dsaparam -out /etc/nginx/dhparam.pem 4096;

This is my /etc/nginx/nginx.conf configuration:

user www-data;
worker_processes 1;
worker_rlimit_nofile 100000;
error_log /var/log/nginx/error.log crit;
pid /var/run/nginx.pid;

events
{
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http
{
    # SSL Security
    ssl_protocols TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
    ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
    ssl_session_timeout 10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off; # Requires nginx >= 1.5.9
    ssl_stapling on; # Requires nginx >= 1.3.7
    ssl_stapling_verify on; # Requires nginx => 1.3.7
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block"; 

    // ... other settings omitted out

    # Load vHosts
    include /etc/nginx/conf.d/*.conf;
}

P.S. I got the nginx security config from https://cipherli.st

and this is my server (virtual host) /etc/nginx/conf.d/example.com.conf config:

## Nginx php-fpm upstream
upstream php73-fpm {
    server localhost:9001 max_fails=3 fail_timeout=30;
    server localhost:9002 max_fails=3 fail_timeout=30;
}

## Redirect insecure traffic to secure site
server {
    listen 80;
    server_name example.com www.example.com;
    return 302 https://www.example.com$request_uri;
}

## Web Server Config
server
{
    ## Server info
    listen 443 default_server ssl;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    server_name example.com www.example.com;
    root /home/www-data/example/src/public;
    index index.html index.php;

    ## DocumentRoot setup
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        expires 30d;
    }

    ## Disable .htaccess and other hidden files
    location  /. {
        return 404;
    }

    ## Execute php scripts
    location ~ \.php$ {
        fastcgi_index index.php;
        fastcgi_pass php73-fpm;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_split_path_info ^(.+\.(?:php))(/.*)$;
        fastcgi_intercept_errors on;
        include fastcgi_params;
        try_files $uri = 404;
        expires off;
    }
}

After setting these up, I restarted my nginx and php-fpm and when I visited my site, it's failing to load in chrome with this error:

This site can’t be reached
The connection was reset.

I checked if nginx was running and it appears to be:

[root@server nginx]# service nginx status
nginx (pid  11781) is running...

[root@server nginx]# netstat -tlpn | grep nginx
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      11781/nginx         
tcp        0      0 0.0.0.0:443                 0.0.0.0:*                   LISTEN      11781/nginx         

I am not seeing any obvious errors in /var/log/nginx either. Any ideas?

6
  • Check if nginx is started and actually listening on port 443 with netstat -tlpn – digijay Sep 28 '19 at 12:22
  • @digijay yes it's running, see updated question with netstat output. – Latheesan Sep 28 '19 at 12:42
  • Could you try to make it listen for ipv6 traffic by adding listen [::]:443 default_server ssl;? I admit that it's just a guess. – digijay Sep 28 '19 at 12:52
  • That didn't help unfortunately. – Latheesan Sep 28 '19 at 12:55
  • What do the NGINX logs say? – Ginnungagap Sep 28 '19 at 13:24
0

Okay, I've managed to resolve the issue myself.

It appears setting TLS protocol to only v1.3 doesn't seem to be working, even though my nginx version is definitely > 1.13.0.

After some digging around, I found out why TLS v1.3 doesn't work on Amazon Linux. It's because the version of OpenSSL required for this to work is 1.1.1 and Amazon Linux has OpenSSL 1.0.2k-fips 26 Jan 2017 (at the time of writing this answer).

Also, since I have ssl_stapling turned on, I forgot to point to the valid cert file in my domain.com.conf.

After making necessary changes; I've tested it on https://www.ssllabs.com/ssltest and I got A+ score, so this will do for now.


Here's the working configuration for me:

nginx.conf

user www-data;
worker_processes 1;
worker_rlimit_nofile 100000;
error_log /var/log/nginx/error.log crit;
pid /var/run/nginx.pid;

events
{
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http
{
    # SSL Security
    ssl_protocols TLSv1.2 TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
    ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
    ssl_session_timeout 10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off; # Requires nginx >= 1.5.9
    ssl_stapling on; # Requires nginx >= 1.3.7
    ssl_stapling_verify on; # Requires nginx => 1.3.7
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    // ... other http configs
}

domain.com.conf

## Nginx php-fpm upstream
upstream php73-fpm {
    server localhost:9001 max_fails=3 fail_timeout=30;
    server localhost:9002 max_fails=3 fail_timeout=30;
}

## Redirect insecure traffic to secure site
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 302 https://www.example.com$request_uri;
}

## Web Server Config
server
{
    ## Server info
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    server_name example.com www.example.com;
    root /home/www-data/example/src/public;
    index index.html index.php;

    ## DocumentRoot setup
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        expires 30d;
    }

    ## Disable .htaccess and other hidden files
    location  /. {
        return 404;
    }

    ## Execute php scripts
    location ~ \.php$ {
        fastcgi_index index.php;
        fastcgi_pass php73-fpm;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_split_path_info ^(.+\.(?:php))(/.*)$;
        fastcgi_intercept_errors on;
        include fastcgi_params;
        try_files $uri = 404;
        expires off;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.