Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nginx-proxy doesn't https 301 auto redirect #461

Closed
sandrodz opened this issue May 17, 2016 · 17 comments
Closed

nginx-proxy doesn't https 301 auto redirect #461

sandrodz opened this issue May 17, 2016 · 17 comments

Comments

@sandrodz
Copy link

sandrodz commented May 17, 2016

I'm facing weird issue, all other sites are properly redirected with 301 via nginx-proxy. but 1 domain returns 200 instead of 301.

curl -k --head portfolio.sandrophoto.com
HTTP/1.1 200 OK
Server: nginx/1.9.12
Date: Tue, 17 May 2016 12:36:49 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.21
X-Pingback: https://portfolio.sandrophoto.com/xmlrpc.php

curl -k --head sandrophoto.com          
HTTP/1.1 301 Moved Permanently
Server: nginx/1.9.12
Date: Tue, 17 May 2016 12:37:15 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://sandrophoto.com/
VIRTUAL_HOST: |
      sandrophoto.com,
      www.sandrophoto.com,
      portfolio.sandrophoto.com
LETSENCRYPT_HOST: |
      sandrophoto.com,
      portfolio.sandrophoto.com

I don't see anything alarming in logs neither of nginx-proxy nor the nginx-webserver. Is there any reason why it would fail redirect?

btw, going to https directly works fine, so ssl keys are generated and ready.

p.s. redirect atm is done via php, this is why I'm checking headers with curl. something seems off.

@wader
Copy link

wader commented May 17, 2016

Hi, can you provide more config and generated nginx config? no HTTPS_METHOD=noredirect involved? can you clarify what you mean by redirect is done via php? the http -> https redirect?

@sandrodz
Copy link
Author

webserver
  image: nginx:latest
  container_name: webserver
  ports:
    - "127.0.0.1::80"
    - "127.0.0.1::443"
  links:
    - php5-fpm
    - php7-fpm
  restart: always
  environment:
    VIRTUAL_HOST: |
      www.sandrophoto.com,
      portfolio.sandrophoto.com
    LETSENCRYPT_HOST: |
      sandrophoto.com,
      portfolio.sandrophoto.com
    LETSENCRYPT_EMAIL: support@weare.de.com
  volumes:
    - ./sites:/etc/nginx/sites
    - ./nginx.conf:/etc/nginx/nginx.conf
    - ./nginx-wp-common.conf:/etc/nginx/nginx-wp-common.conf
    - ./nginx-php-common.conf:/etc/nginx/nginx-php-common.conf
    - /srv/www:/www

nginx-proxy:
  image: jwilder/nginx-proxy
  container_name: nginx-proxy
  ports:
    - "80:80"
    - "443:443"
  restart: always
  environment:
    - DEFAULT_HOST=njord.weare.de.com
  volumes:
    - /srv/certs:/etc/nginx/certs:ro
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - ./vhost.d:/etc/nginx/vhost.d
    - /usr/share/nginx/html


nginx-certs:
  image: jrcs/letsencrypt-nginx-proxy-companion
  container_name: nginx-certs
  volumes:
    - /srv/certs:/etc/nginx/certs:rw
    - /var/run/docker.sock:/var/run/docker.sock:ro
  volumes_from:
    - nginx-proxy

nginx default

upstream 
portfolio.sandrophoto.com
 {
                ## Can be connect with "bridge" network
            # webserver
            server 172.17.0.8:80;
}
server {
    server_name 
portfolio.sandrophoto.com
;
    listen 80 ;
    access_log /var/log/nginx/access.log vhost;
    include /etc/nginx/vhost.d/default;
    location / {
        proxy_pass http://portfolio.sandrophoto.com;
    }
}
upstream 
sandrophoto.com {
                ## Can be connect with "bridge" network
            # webserver
            server 172.17.0.8:80;
}
server {
    server_name 
sandrophoto.com;
    listen 80 ;
    access_log /var/log/nginx/access.log vhost;
    return 301 https://$host$request_uri;
}
server {
    server_name 
sandrophoto.com;
    listen 443 ssl http2 ;
    access_log /var/log/nginx/access.log vhost;
    ssl_protocols 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: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_prefer_server_ciphers on;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;
    ssl_certificate /etc/nginx/certs/sandrophoto.com.crt;
    ssl_certificate_key /etc/nginx/certs/sandrophoto.com.key;
    ssl_dhparam /etc/nginx/certs/sandrophoto.com.dhparam.pem;
    add_header Strict-Transport-Security "max-age=31536000";
    include /etc/nginx/vhost.d/default;
    location / {
        proxy_pass http://sandrophoto.com;
    }
}

@sandrodz
Copy link
Author

I've dozens of other domains on this server next to those problematic and they all work fine, and default contains correct redirects. just this subdomain portfolio.sandrophot.com fails.

atm I'm doing http -> https redirect on the application side, wordpress handles this internally. but problem was apparent from the very beginning, even before configuring wp.

@kamermans
Copy link
Contributor

Perhaps nginx-proxy doesn't realize that the SSL certificate (presumably *.sandrophoto.com) should be used for portfolio.sandrophoto.com, and so it does not do the HTTPS redirect, although if that is true it would be a bug in nginx-proxy since you said that HTTPS does indeed work through nginx-proxy when you go there directly. You could try add CERT_NAME=sandrophoto.com to the env vars of webserver to force it to use that certificate (assuming the cert is sandrophoto.com.<crt|.key>). Since the nginx config you posted for portfolio.sandrophoto.com does not contain an SSL section, I would be curious to see if that is a wildcard cert or if it is just for sandrophoto.com, or if it has portfolio.sandrophoto.com as an alternate name.

@sandrodz
Copy link
Author

sandrodz commented May 17, 2016

well that nginx server has a lot of domains attached. and some with subdomains, all work just fine.

in certs dir I've:

screen shot 2016-05-18 at 12 44 03 am

screen shot 2016-05-18 at 12 45 53 am

screen shot 2016-05-18 at 12 46 21 am

all other domains and subdomains work as expected except that one... this is the weird part.

@sandrodz
Copy link
Author

it fixed itself

screen shot 2016-05-18 at 12 51 37 am

@kamermans
Copy link
Contributor

Well, that's good and bad. Glad your problem is fixed, but if it's not reproduceable, it will be tough to fix it :). We should add a bit more verbosity to nginx-proxy so it logs every VIRTUAL_HOST that it adds, along with any associated SSL certs that it has found for them and which container they point to. This would have solved the problem of whether or not nginx-proxy was even aware that there was a relevant certificate. I imagine now the nginx config shows the SSL vhost for portfolio.sandrophoto.com, which it didn't before, and this leads me to believe some docker event triggered docker-gen to recreate the config.

@sandrodz
Copy link
Author

yes, I was browsing default.conf and noticed that ssl part appeared for that subdomain. I check with curl and in fact it was working. and yes I realise intermittent issues are the hardest to debug.

I've a gut feeling that this is problem of dns propagation, I've noticed that cname propagates slower than root domain ip change, even though TTL is the same. There is some caching going on somewhere.

sometimes letsencrypt companion shows these errors:
ERROR:simp_le:1271: CA marked some of the authorizations as invalid, which likely means it could not access http://example.com/.well-known/acme-challenge/X. Did you set correct path in -d example.com:path or --default_root? Is there a warning log entry about unsuccessful self-verification? Are all your domains accessible from the internet? Failing authorizations: https://acme-v01.api.letsencrypt.org/acme/authz/GXX7BsnVlSt4ALDMBgylUlSTKBcMBMvKt13u-Sb8kzo Challenge validation has failed, see error log.

even though I didn't see this error for that particular domain, I've a feeling its related.

@wader
Copy link

wader commented May 17, 2016

Looking at https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/blob/efc7e4c2d98e7f0422622ebb102d216d80dbbc66/app/functions.lib#L72 i would not be surprised if it could cause some race condition, it seems to fire of execs and signals that might might stumble upon each other.

@wader
Copy link

wader commented May 17, 2016

@JrCs any ideas?

@JrCs
Copy link

JrCs commented May 18, 2016

No i don't have ideas. Sorry.

@wader
Copy link

wader commented May 18, 2016

@JrCs Ok, btw is there a good reason for https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/blob/efc7e4c2d98e7f0422622ebb102d216d80dbbc66/app/letsencrypt_service#L96 being reload_nginx instead of reload_nginx='true'. Might make things stabler.

@JrCs
Copy link

JrCs commented May 19, 2016

Yes, we only need to reload_nginx if we create a new block location for the specific domain. If we don't have a specific domain configuration (so nginx use the default.conf) there's no need to reload nginx.

@wader
Copy link

wader commented May 19, 2016

@JrCs I was more referring to why it uses reload_nginx in the loop stead of reload_nginx='true' and then just reload nginx once at the end of update_certs.

@wader
Copy link

wader commented May 19, 2016

@JrCs My thinking is that running nginx -s reload sends a reload signal but it will not wait for nginx daemon to actually read the new config... so what happens if another "/usr/local/bin/docker-gen -only-exposed /app/nginx.tmpl /etc/nginx/conf.d/default.conf; /usr/sbin/nginx -s reload" is executed (not unlikely as it done in a loop in the script) in the container while the daemon is reloading? signal is ignored and you will end up with previous config or it reads corrupt/partial config, something else?

If that is the case there is probably also a similar issue for how the docker-gen process in the nginx-proxy container generates config and reloads nginx on docker events without any synchronization with execs done by docker-letsencrypt-nginx-proxy-companion

@ghost
Copy link

ghost commented Jul 5, 2016

I had a similar issue (not the same) that was fixed by adding VIRTUAL_PROTO=https to the site containers environment.

@tkw1536
Copy link
Collaborator

tkw1536 commented Apr 10, 2022

Resolved per last comment, closing.

@tkw1536 tkw1536 closed this as completed Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants