AWS API-Gateway client authentication and NGINX - ssl

Currently i try to implement the AWS API Gateway Client Authentication with NGINX Backend Servers. I want to prevent access to my api except than AWS API-Gateway. I have created a client certificate on the AWS API Gateway Console(PEM encoded) and set up my virtual host config as follows. I'm using already a CA signed wildcard certificate to access the subdomain.
server {
listen 443;
server_name api.example.com;
if ($bad_client) { return 403; }
root /usr/share/nginx/api.example.com/public;
index index.php;
ssl on;
ssl_stapling on;
ssl_trusted_certificate aws-cert.pem;
ssl_verify_client on;
ssl_certificate /etc/nginx/ssl/ca-bundle.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_session_timeout 10m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
error_page 404 /404.html;
location /404.html {
internal;
}
location / {
try_files $uri.html $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_VALUE "error_log=/var/log/php5-fpm.log";
}
location ~ /\.ht {
deny all;
}
}
I get the following error message and the whole nginx service is not available any more. The docs of Amazon are not very helpful. What i'm doing wrong?
https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html
[emerg] 19636#0: no ssl_client_certificate for ssl_client_verify

In order for Nginx to verify the client, you need to tell it which certificate the client will be using. In my config I have:
# Client auth via certs
ssl_client_certificate /etc/nginx/ssl/cert.pem;
ssl_trusted_certificate /etc/nginx/ssl/cert.pem;
ssl_verify_client on;
I'm not entirely clear on the difference between the ssl_client_certificate and ss_trusted_certificate directives; perhaps somebody else can explain that.
Docs here.

Related

Trying to get one page in nginx to redirect to http and all the others to https

I am using CakePHP 2.9 in Ubuntu 16, and nginx, and I have a vps with a ssl certificate installed on it, and I want to use javascript websockets with php ratchet. The problem is that they don't work, out of the box. For example, without changing a certain setting in firefox about:config, I can't use ws websockets in the browser (that's no good, if I want other people to be able to use it). But I also can't get PHP Ratchet to accept wss websockets. So, I'm trying to redirect the page where the websockets are going to run back to http, so I can use regular ws and connect to PHP ratchet.
The problem is, that I can't seem to get my nginx config file to do that smoothly. I have it redirecting on the page I want to use websockets for, but it seems to give a 404 error. This could be an issue with my DNS for the site perhaps, but here is the nginx config I am using:
server {
listen 80;
listen [::]:80;
server_name server.com;
location /websocket_path {
}
location / {
return 301 https://$server_name/web/$request_uri/;
}
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm index.php;
ssl on;
ssl_certificate /ssl_path/cert_chain.crt;
ssl_certificate_key /ssl_path/server.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
location /web {
alias /usr/share/nginx/html/web/app/webroot;
try_files $uri $uri/ /web/app/webroot/index.php;
}
server_name server.com;
location = / {
return 301 https://$server_name/web/$request_uri/;
}
location /websocket_path {
return 301 http://$server_name/websocket_path;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
#include fastcgi_params;
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /.well-known {
allow all;
}
location ~ /.sandbox {
}
location ~* \.(?:manifest:appcache|htm?|xml|json)$ {
expires -1;
}
}
Any help on this matter would be greatly appreciated. Thank you.

Serve sub-directory inside a root as another sub-domain with SSL

I have a working NGINX configuration for multiple sub-domains. I have enabled SSL for them by using a Let's Encrypt/ACME client. All of the sub-domains are working except one.
One of the sub-domain is served under /var/www/dir as https://dir.domain.net and another one is served under /var/www/dir/one as https://one.domain.net. For some reason I can not understand, the sub-domain served under /var/www/dir/one is being redirected to https://dir.domain.net after enabling SSL.
Configurations for this two sub-domains as follow:
/var/www/dir as http://dir.domain.net
server {
listen 80;
listen 443 ssl spdy;
root /var/www/dir;
index index.php index.html index.htm;
server_name dir.domain.net;
add_header Strict-Transport-Security max-age=31536000;
add_header X-Frame-Options SAMEORIGIN;
ssl on;
ssl_certificate cert.crt;
ssl_certificate_key key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate trustedCA.pem;
resolver 8.8.4.4 8.8.8.8 valid=1800s;
resolver_timeout 10s;
ssl_dhparam dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
location / {
try_files $uri $uri/ /index.html =404;
rewrite /index.php/(topic|board),(.*).html$ /index.php?$1=$2 permanent;
rewrite /index.php/(topic|board),(.*)$ /index.php?$1=$2 permanent;
rewrite /index.php(\?|%3F)(topic|board)(=|%3D)(.*)$ /index.php?$2=$4 permanent;
rewrite /subdomains/dir/index.php/(topic|board),(.*)$ /index.php?$1=$2 permanent;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_read_timeout 90;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SSL_PROTOCOL $ssl_protocol;
fastcgi_param SSL_CIPHER $ssl_cipher;
fastcgi_param SSL_SESSION_ID $ssl_session_id;
fastcgi_param SSL_CLIENT_VERIFY $ssl_client_verify;
include fastcgi_params;
}
}
/var/www/dir/one as https://one.domain.net:
server {
root /var/www/dir/one;
index index.php index.html index.htm;
server_name one.domain.net;
# log directives
add_header Strict-Transport-Security max-age=31536000;
add_header X-Frame-Options SAMEORIGIN;
ssl on;
ssl_certificate cert.crt;
ssl_certificate_key key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate trustedCA.pem;
resolver 8.8.4.4 8.8.8.8 valid=1800s;
resolver_timeout 10s;
ssl_dhparam dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS;
location / {
try_files $uri $uri/ /index.html;
rewrite /index.php/(.*)$ /index.php?title=$1 permanent;
}
location ~ \.php$ {
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass phpservers;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
In order to serve /var/www/dir/one as https://one.domain.net, what should I do?
Thanks in advance.

nginx ssl_certificate directive doesn't work within server block, browser shows ERR_CONNECTION_CLOSED or ERR_CONNECTION_RESET

I'm trying to serve multiple TLS-secured domains out of a single VPS with Nginx v1.8.0, but for some reason it's just not taking the certificate configuration in the server block. When I put the ssl_certificate and ssl_certificate_key directives in the http block, it works fine. But when I try to put them into the server block instead, there are no errors at startup, nothing in the logs, but chrome gives me an ERR_CONNECTION_CLOSED message. This has to be easier than it seems....
Here's the setup that works:
nginx -V output:
nginx version: nginx/1.8.0
built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled
My main nginx.conf:
user http;
worker_processes 3;
pid /var/run/nginx.pid;
error_log /var/log/nginx_error.log error;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type text/plain;
sendfile on;
keepalive_timeout 65;
index index.php index.html;
log_format main '$remote_addr - $remote_user [$time_local], "$scheme://$host$request_uri", '
'file: "$request_filename", http: $status, sent: $body_bytes_sent, ref: "$http_referer", '
'"$http_user_agent", "$http_x_forwarded_for"';
access_log /var/log/nginx_access.log main;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server {
listen 80;
server_name "";
return 410;
}
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
include vhosts/*.conf;
}
My vhosts directory listing:
site1.conf
site2.conf
And finally, my site1.conf file (site2.conf is essentially the same):
# Server block that redirects www.site1.com requests to site1.com
server {
listen 443;
server_name www.site1.com;
return 301 https://site1.com$request_uri;
}
# Server block that serves site1.com;
server {
listen 443 ssl;
server_name site1.com;
root /srv/www/site1/public_html;
index index.php index.html index.htm;
error_log /var/log/nginx_err_site1.log error;
access_log /var/log/nginx_acc_site1.log main;
include global_restrictions.conf;
location / {
try_files $uri /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri = 404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm_site1.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
As you can see, the ssl... directives are in the main configuration file http block. That configuration works fine. If I remove them from that location, however, and put them into the server block of the site1.conf vhost file, as indicated below, I get the ERR_CONNECTION_CLOSED error.
# Server block that redirects www.site1.com requests to site1.com
server {
listen 443;
server_name www.site1.com;
return 301 https://site1.com$request_uri;
}
# Server block that serves site1.com;
server {
listen 443 ssl;
server_name site1.com;
root /srv/www/site1/public_html;
index index.php index.html index.htm;
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
error_log /var/log/nginx_err_site1.log error;
access_log /var/log/nginx_acc_site1.log main;
include global_restrictions.conf;
location / {
try_files $uri /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri = 404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm_site1.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
I just can't figure it out!
Thanks for any help you can offer.
Just got back to this after more than a month (ok, so my launch is a little delayed, whatever! ;) ).
Indeed, the answer was as easy as I supposed it had to be.
I had viewed those little "www." redirect blocks as simple bounces, and for some reason didn't feel I had to include information about the certificates in those blocks. However, because of the way secure connections work, the server has to fully establish a secured connection before issuing a response (i.e. redirect instruction), so because I wasn't including the certificate information in those little redirect blocks, it was giving me errors (and frustratingly, it wasn't telling me what those errors were).
So in the end, the solution was simply to add the valid ssl_certificate and ssl_certificate_key directives in each server block that listened on port 443. All works well now!
Just to fully illustrate the point, this is my updated and WORKING site1.conf (and site2.conf, which is virtually identical):
# Server block that redirects www.site1.com requests to site1.com
server {
listen 443 ssl;
server_name www.site1.com;
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
return 301 https://site1.com$request_uri;
}
# Server block that serves site1.com requests
server {
listen 443 ssl;
server_name site1.com www.site1.com;
root /srv/www/site1/public_html;
ssl_certificate /etc/letsencrypt/live/site1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.com/privkey.pem;
index index.php index.html index.htm;
error_log /var/log/nginx_err_site1.log error;
access_log /var/log/nginx_acc_site1.log main;
include global_restrictions.conf;
location / {
try_files $uri /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri = 404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm_site1.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
And my nginx.conf file now no longer has the ssl_certificate lines in it.

ERR_CONNECTION_REFUSED on nginx Raspberry Pi Home Server

Basically, I have created a site and purchased an SSL certificate. Everything worked fine, I linked up the certificate in the config of the site, but then it suddenly stopped working. My linked site configuration, where I replaced my site with 'example.com', is as follows:
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
# Get SSL setup
ssl on;
ssl_certificate /etc/nginx/ssl/site.crt;
ssl_certificate_key /etc/nginx/ssl/site.key;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_timeout 1d;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
# Enable HSTS ( see http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security )
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/site.crt;
resolver 8.8.8.8;
server_name www.example.com example.com;
root /var/www/html;
index index.php index.html index.htm;
error_log /var/www/html/logs/error.log;
access_log /var/www/html/logs/access.log;
error_page 404 /404.html;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Now, my site doesn't even work on a local IP address (192.168.1.x). Can someone please offer a solution?
Thank you.

SSL only works without www

My SSL certificate works perfectly if my URL is site.com but not www.site.com. Why is this, and how can I fix it? When I configured my CSR and certificate, it said to use mysite.com as the domain, and not www.mysite.com, as it auto-configures www.
Here is my nginx configuration:
ssl_certificate /etc/nginx/ssl/bundle.crt;
ssl_certificate_key /etc/nginx/ssl/myserver.key;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-$
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
server {
listen 80;
listen 443 ssl;
keepalive_timeout 70;
access_log /var/www/mysite.com/logs/access.log;
error_log /var/www/mysite.com/logs/error.log;
root /var/www/mysite.com/public_html/mysite/public/_main;
server_name www.mysite.com mysite.com;
# HSTS - 6 months
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
resolver 192.0.2.1;
location / {
try_files $uri $uri.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
if ($uri !~ "^/assets/images/") {
fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
}
fastcgi_index landing.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Usually, it's the opposite that is true. If you specify www.yoursite.com as the common name in your CSR, then the certificate will work with www.yoursite.com and yoursite.com.