-2

I have a server in node.js, completed and listening to HTTP.

I want to use a load balancer, and read about NginX, and discovered it could handle HTTPS.

Is it possible to use NginX to handle HTTPS, and retrieve the information from my server in HTTP, before sending them in HTTPS? Is it good practice? Or a awfully wrong thing to do?

  • 1
    That is called SSL (or rather TLS) off-loading or SSL termination and quite common. One thing to consider is that if your application generates call-back URL's you want them to be relative, i.e. href=/css/style.css and not HTTP://internalhostname:80/css/style.css – HBruijn Aug 7 '16 at 14:50
  • @HBruijn: The term SSL/TLS offloading was exactly what I needed and putted me on the right tracks :) – DrakaSAN Aug 8 '16 at 13:08
1

Yes, this is reasonable and common. Here is the configuration I use for Wordpress in a similar situation. I use fastcgi_pass, but you may perhaps need to use proxy_pass instead, depending on what you're sending the requests too.

I have a Wordpress / Nginx tutorial that goes into this works. It's not exactly what you need, but it's close.

# Rate limiting for logins
limit_req_zone $binary_remote_addr zone=login:1m rate=1r/s;

# Caching. Putting the cache into /dev/shm keeps it in RAM, limited to 10MB, for one day.
# You can move to disk if you like, or extend the caching time / size
fastcgi_cache_path /dev/shm/abc_nginxcache levels=1:2 keys_zone=SP:50m inactive=1440m; #RAM

# http production wordpress multisite server
server {
  server_name www.example.com example.com;
  listen 443 ssl http2;

  ssl_certificate /var/lib/acme/certs/***CERT_DIRECTORY/fullchain;
  ssl_certificate_key /var/lib/acme/certs/***CERT_DIRECTORY/privkey;

  # Set up preferred protocols and ciphers. TLS1.2 is required for HTTP/2
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  # This tells the browser not to bother trying to use http for an hour - it should probably
  # be put up to a week or so, and leave it disabled for testing
  # add_header Strict-Transport-Security "max-age=3600" always;
  # This does the same but for subdomains as well
  # add_header Strict-Transport-Security "max-age=3600; includeSubDomains" always;

  root /var/www/***FOLDER;

  # First line is a cached access log, second logs immediately which is better for debugging
  access_log  /var/log/nginx/access.log main buffer=128k flush=1m if=$log_ua;
  #access_log  /var/log/nginx/access.log main;

  # Send HipHop and PHP requests to HHVM, a fast PHP interpreter
  location ~ \.(hh|php)$ {
    fastcgi_keep_conn on;
    fastcgi_intercept_errors on;
    fastcgi_pass   php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;

    # Use the cache defined above. Cache 200 (success) status's, for 24 hours, and cache
    # specific other status's for an hour. This helps mitigate DDOS attacks.
    fastcgi_cache SP;
    fastcgi_cache_valid 200 1440m;
    fastcgi_cache_valid 403 404 405 410 414 301 302 307 60m;
    add_header X-Cache $upstream_cache_status; # This can be removed if desired

    fastcgi_cache_methods GET HEAD; 
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;

    # Set the cache control headers we prepared earlier. Remove the old unnecessary Pragma and hide the server
    # version. Remove the cache control header that comes back from Wordpress as it's often incorrect
    more_clear_headers "Cache-Control";
    more_clear_headers "Pragma"; more_clear_headers Server; more_clear_headers "Expires";
    add_header Cache-Control $cacheControl;

    # add_header Z_LOCATION "wpmu PHP MAIN"; add_header URI $uri; add_header Z_CACHE_CONTROL $cacheControl; # Nginx Debugging
  }
}

# Forward non-www requests to www
server {
    listen       80;
    server_name  example.com www.example.com;
    access_log  /var/log/nginx/access.log main buffer=128k flush=1m if=$log_ua;
    return       301 https://www.example.com$request_uri;
}

server {
  listen 443 ssl http2;
  server_name example.com;

  ssl_certificate /var/lib/acme/certs/***CERT_DIRECTORY/fullchain;
  ssl_certificate_key /var/lib/acme/certs/***CERT_DIRECTORY/privkey;

  # Set up preferred protocols and ciphers. TLS1.2 is required for HTTP/2
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

  access_log  /var/log/nginx/access.log main buffer=128k flush=1m if=$log_ua;

  return 301 https://www.example.com$request_uri;
}
-1

Yes, you can do it and it is a common thing to do in such setup.

You'll need 2 server directives in your nginx config - one for port 80 and one for port 443. Second one should be doing the same thing as first one, except it also should apply SSL to connections somehow like that:

server {
  listen 80;
  ....
  ... your other directives here
}

ssl_certificate     /path/to/server.crt;
ssl_certificate_key /path/to/server.key;

server {
  listen 443 ssl;
   ....
  ... your other directives here
}
  • This is not best practice. You should forward port 80 to 443 as I described in my answer. – Tim Aug 5 '16 at 19:04
  • Rewriting schema from http to https depends heavily on users needs and application behind nginx. There are cases when redirecting all requests to https can lead to breaking of some open api, for example, if it is used by clients not following redirects. If you have simple wordpress site, then it is, of course, a good idea. But I left this decision to creator of question with your other directives here part. – Pavel Kazhevets Aug 5 '16 at 19:55
  • Sure, it may make sense in some situations. If you specifically want security you forward from HTTP, and if you're interested in SEO it's better to serve content from a single URL. – Tim Aug 5 '16 at 21:35

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.