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?

Latheesan
  • 357
  • 2
  • 6
  • 19
  • 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
  • Not much: [root@server ~]# tail -50 /var/log/nginx/error.log 2019/09/28 11:06:02 [notice] 11317#0: signal process started 2019/09/28 11:06:04 [notice] 11319#0: signal process started 2019/09/28 11:39:00 [notice] 11752#0: signal process started 2019/09/28 11:39:03 [notice] 11754#0: signal process started – Latheesan Sep 28 '19 at 13:26

1 Answers1

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;
    }
}
Latheesan
  • 357
  • 2
  • 6
  • 19