NGINX 2 domains on the same IP, want to redirect both to HTTPS - redirect

I have 2 domains running on my server, NGINX just proxies them to node apps. I have a certificate for one, but for the other I'm just using cloudflare to provide HTTPS. I want to ensure that when users visit either domain, they always get redirected to the HTTPS version of the domain, without a www. This is my current configuration, uncommenting the block for the domain2 configuration file seems to break both sites :(
domain1 config file:
upstream domain1.com {
server 127.0.0.1:8000;
keepalive 8;
}
server {
listen 0.0.0.0:80;
server_name domain1.com www.domain1.com;
return 301 https://domain1.com$request_uri;
}
server {
#listen 80;
listen 443 ssl http2;
server_name domain1.com;
access_log /var/log/nginx/domain1.com.log;
root /var/www/domain1.com/client/public;
include /etc/nginx/global/cloudflare-allow.conf;
ssl_certificate /etc/nginx/ssl/domain1.crt;
ssl_certificate_key /etc/nginx/ssl/domain1.key;
if ($bad_referer) {
return 444;
}
location / {
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_pass http://domain1.com;
proxy_redirect off;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|webp)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
# CSS and Javascript
location ~* \.(?:css|js)$ {
expires 1y;
access_log off;
add_header Cache-Control "public";
}
location ~* \.(?:rss|atom)$ {
expires 1h;
add_header Cache-Control "public";
}
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
}
}
server {
listen 443 ssl http2;
server_name www.domain1.com;
return 301 https://domain1.com$request_uri;
}
domain2 config file:
upstream domain2.com {
server 127.0.0.1:9000;
keepalive 8;
}
#server {
# listen 80;
# server_name domain2.com www.domain2.com;
# return 301 https://$server_name$request_uri;
#}
server {
listen 80;
#listen 443 ssl http2;
server_name domain2.com;
access_log /var/log/nginx/domain2.com.log;
root /var/www/domain2.com;
include /etc/nginx/global/cloudflare-allow.conf;
if ($bad_referer) {
return 444;
}
location / {
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_pass http://domain2.com;
proxy_redirect off;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|webp)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
# CSS and Javascript
location ~* \.(?:css|js)$ {
expires 1y;
access_log off;
add_header Cache-Control "public";
}
location ~* \.(?:rss|atom)$ {
expires 1h;
add_header Cache-Control "public";
}
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
expires -1;
}
}

When SSL is done through CloudFlare's Flexible SSL mode, communication to the origin is HTTP traffic over port 80.
In order to detect whether this traffic is HTTPS you can't use the HTTPS environment variable, you must then check if the X-Forwarded-Proto header is set to HTTPS instead.
You can do this in Nginx as follows:
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$1 permanent;
}
The easier way to do this is to simply set an "Always use HTTPS" Page Rule in CloudFlare.

Related

NGINX not respecting server_name regex

I have this nginx config.. i want it to accept all domains that have the word competitions in it and end with .com.au.. I have tested with a domain name that should NOT be accepted but it reaches the application.. is the server_name being ignore because I'm using a proxy?
server {
listen 80 default_server;
server_name ~^(.+)competitions?(.+)\.com\.au;
access_log /var/log/nginx/$host.access.log;
error_log /var/log/nginx/error.log;
if ($host !~* ^www){
rewrite ^/(.*)$ https://www.$host/$1 permanent;
}
location / {
proxy_no_cache 1;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8888;
try_files $uri $uri/ #proxy;
}
location #proxy {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8888;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = #rewrite_proxy;
}
location #rewrite_proxy {
rewrite /(.*) /index.cfm?path=$1;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8888;
}
}
You'd have to remove the default_server from there, because this is a catch-all directive.And you still could setup another one server with the default_server directive, if required.
See How nginx processes a request for a more detailed explanation:
If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port.

Nginx redirect all www to non www, and http to https

I'm using nginx, let's encrypt and trying to redirect all from http and www to one route - https://example.com. Everything working except https://www.example.com. It doesn't redirect. What am i doing wrong? My code below.
server {
root /var/www/example.com;
index index.html index.php index.htm;
server_name example.com www.example.com;
location ~* ^(?!/phpmyadmin/).+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|tar|wav|bmp|rtf|swf|ico|flv|txt|xml|docx|xlsx)$ {
access_log off;
expires 30d;
}
location ~ /\.ht {
deny all;
}
location / {
proxy_pass http://127.0.0.1:81/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_set_header Host $host;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_redirect off;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://example.com$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name example.com www.example.com;
return 404; # managed by Certbot
}

Facebook messenger bot callback url curl error 35

I am trying to create a facebook messenger bot. every thing work woth heroku. then i transfer it to my own server. then i got the error "curl errno =35" i tried it with ngrok work fine on the server but not work with my server.
using debian with nginx x and letsencrypt.
the url is preetombot.bddevwork.net
my setting
server {
listen 80;
server_name preetombot.bddevwork.net www.preetombot.bddevwork.net;
#root /usr/share/nginx/www/preetombot.bddevwork.net;
#return 301 https://$server_name$request_uri;
}
server {
listen 443 default_server ssl http2;
server_name preetombot.bddevwork.net
www.preetombot.bddevwork.net;
ssl_stapling on;
ssl_stapling_verify on;
ssl_certificate /etc/letsencrypt/live/preetombot.bddevwork.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/preetombot.bddevwork.net/privkey.pem;
ssl_trusted_certificate /test/ca-certs.pem;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM$
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /test/dhparam.pem;
root /usr/share/nginx/www/preetombot.bddevwork.net;
index index.php index.html index.htm;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:5000$request_uri;
proxy_redirect off;
proxy_http_version 1.1;
}
location ~ /.well-known{
allow all;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/www;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I have multiple secure ports listening within a single server, in this case for FB bot I'm using port 8083.
upstream botd {
server application_1:8083 max_fails=3 fail_timeout=30s;
keepalive 64;
}
server {
listen 443 default_server;
listen [::]:443 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
rewrite_log on;
ssl on;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log debug;
ssl_certificate /etc/ssl/techie8.io/api.techie8.io.bundle;
ssl_certificate_key /etc/ssl/techie8.io/api.techie8.io.key;
# Botd skill.
location /botd {
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://botd;
break;
}
}
# Techie8 API.
location / {
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
#Timeout after 8 hours
proxy_read_timeout 43200000;
proxy_connect_timeout 43200000;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://application;
break;
}
}
}
In Flask App:
#app.route('/botd', methods=['GET'])
def handle_verification():
"""Handle Token verification."""
print "Handling Verification."
if request.args.get('hub.verify_token') == VERIFY_TOKEN:
print "Verification successful!"
return request.args.get('hub.challenge')
else:
print "Verification failed!"
return 'Error, wrong validation token'
#app.route('/botd', methods=['POST'])
def handle_messages():
print "Handling Incoming Messages\n"
payload = request.get_data()
print payload
for sender, message in messaging_events(payload):
print "Incoming Message from %s: %s" % (sender, message)
print ("Access Token: %s" % ACCESS_TOKEN)
send_message(ACCESS_TOKEN, sender, message)
return "ok"
In Facebook WebHook Callback URL I have my host configured:
https://api.mycompany.io/botd

Nging redirect http and https to https://domain (without www)

This is my Nginx config:
upstream app_server {
# Bindings to the Gunicorn server
server 127.0.0.1:8002 fail_timeout=0;
}
server {
listen 80;
server_name "~^www\.(.*)$";
return 301 https://$host$request_uri;
}
server {
access_log path_to_nginx-access.log;
error_log path_to_nginx-error.log;
listen 443 ssl;
server_name _;
ssl_certificate path_to_nginx.crt;
ssl_certificate_key path_to_nginx.key;
client_max_body_size 4G;
keepalive_timeout 5;
root path_to_root;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://app_server;
break;
}
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root path_to_templates;
}
}
My goal is to have all this addresses redirecting to https://domain.com
http://domain.com
https://domain.com
http://www.domain.com
https://www.domain.com
What should I change?
Keep in mind that I need to handle multiple domains with the same Nginx server (vide server_name).
Thanks!

How to redirect two domains in ssl?

I have the domain englishname.ca than I want to redirect to englishname.com. I did some configuration and it works with HTTP but not with https. But I go to http://englishname.ca, I'm redirected to http://englishname.com but when I go to https://englishname.ca, I'm not redirected.
This is my conf :
server {
server_name 162.243.216.109 staging.frenchname.com staging.englishname.ca staging.singularenglishname.com;
add_header X-Frame-Options "SAMEORIGIN";
rewrite ^/(.*)$ $scheme://staging.englishname.com/$1 permanent;
}
server {
listen 80 default deferred;
server_name www.englishname.com staging.englishname.com;
root /home/deployer/apps/site/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
server {
listen 443 default ssl;
server_name www.englishname.com staging.englishname.com;
root /home/deployer/apps/site/current/public;
ssl on;
ssl_certificate /etc/ssl/certs/www.englishname.crt;
ssl_certificate_key /etc/ssl/private/www.englishname.key;
ssl_session_timeout 5m;
ssl_protocols sslv3 tlsv1 tlsv1.1 tlsv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
What can I do?
I found the answer, I simply added those lines :
server {
listen 443;
server_name 162.243.216.109 staging.lescollectionneursassocies.com staging.associatedartcollectors.ca staging.associatedartcollector.com;
add_header X-Frame-Options "SAMEORIGIN";
rewrite ^/(.*)$ $scheme://staging.associatedartcollectors.com/$1 permanent;
}
It's the same lines than the beggin but with listen 443.