如何配置Nginx将https流量重定向到我的Springboot应用程序

时间:2019-03-05 00:17:43

标签: spring-boot ssl nginx certbot

我正在关注堆栈问题How can I set up a letsencrypt SSL certificate and use it in a Spring Boot application? 配置我的Springboot应用程序以使用https(certbot),但是我的Nginx无法正确重定向到我的应用程序。

更多上下文: 我正在使用Cloudflare将www.example.com(我的域)请求重定向到装有Nginx和Springboot应用程序的计算机。我希望Nginx将端口80请求上的此HTTP重定向到在端口8443(https)上运行的应用程序。我已经安装了certbot(letsencrypt)证书,并使用这些证书设置了我的nginx配置。

生成证书后的配置如下:

Springboot application.properties

server.port=8443
security.require-ssl=true
server.ssl.key-store=/etc/letsencrypt/live/mydomain/keystore.p12
server.ssl.key-store-password=mydomain
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=myAlias

更新1 >> Nginx /etc/nginx/nginx.conf

pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {

    log_format formatWithUpstreamLogging '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request';

    access_log  /var/log/nginx/access.log formatWithUpstreamLogging;
    error_log   /var/log/nginx/error.log;

    server {

      listen 80;

      server_name www.example.com example.com;

      return 301 https://$server_name$request_uri;

    }

   # SSL configuration
    server {

       listen 443 ssl;
       server_name www.example.com example.com;

       ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; 
       ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

       location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass https://localhost:8443/;
       }
    }
}    

nginx -T命令的输出

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {

    log_format formatWithUpstreamLogging '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request';

    access_log  /var/log/nginx/access.log formatWithUpstreamLogging;
    error_log   /var/log/nginx/error.log;

    server {    

      listen 80;

      server_name www.example.com example.com;

      return 301 https://$server_name$request_uri;

    }

   # SSL configuration
    server {

       listen 443 ssl;
       server_name www.example.com example.com;

       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
       location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass https://localhost:8443/;
       }
   }
}   

nginx -T命令的输出

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {

    log_format formatWithUpstreamLogging '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request';

    access_log  /var/log/nginx/access.log formatWithUpstreamLogging;
    error_log   /var/log/nginx/error.log;

    server {    

      listen 80;

      server_name www.example.com example.com;

      return 301 https://$server_name$request_uri;

    }

   # SSL configuration
    server {

       listen 443 ssl;
       server_name www.example.com example.com;

       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
       location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass https://localhost:8443/;
       }
   }
}   

更新2 >>> Nginx /etc/nginx/nginx.conf

    pid /run/nginx.pid;

    events {
        worker_connections 768;
    }

    http {

        log_format formatWithUpstreamLogging '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request';

        access_log  /var/log/nginx/access.log formatWithUpstreamLogging;
        error_log   /var/log/nginx/error.log;

    server {

      listen 80;

      server_name www.codeonblue.com.br codeonblue.com.br;

       ssl_certificate /etc/letsencrypt/live/codeonblue.com.br/fullchain.pem; # managed by Certbot
       ssl_certificate_key /etc/letsencrypt/live/codeonblue.com.br/privkey.pem;

        # managed by Certbot
       location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass https://localhost:8443/;
       }


    }    
 }

当我启动nginx和springboot应用程序并尝试在 Chrome 中访问www.example.com时,我会看到此页面(下图)

Error in Chrome

当我尝试通过 Firefox 访问时,会看到以下内容: enter image description here

因为/var/log/nginx/error.log没有条目,所以我检查了访问日志,并且有很多这样的请求(尽管我只做了一个请求):

Nginx访问日志(/var/log/nginx/access.log)

[06/Mar/2019:12:59:52 +0000] <same-IP-address> - - - www.example.com to: -: GET / HTTP/1.1

以下是卷曲结果:

卷曲-I https://www.example.com/

HTTP/1.1 301 Moved Permanently
Date: Wed, 06 Mar 2019 14:32:26 GMT
Content-Type: text/html
Connection: keep-alive
Set-Cookie: __cfduid=d330e880850b37d5a9870c1edb71ab8c01551882746; expires=Thu, 05-Mar-20 14:32:26 GMT; path=/; domain=.example.com; HttpOnly
Location: https://www.example.com/
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 4b3509fdb8e0c879-MIA

卷曲-I http://www.example.com/

HTTP/1.1 301 Moved Permanently
Date: Wed, 06 Mar 2019 14:32:56 GMT
Content-Type: text/html
Connection: keep-alive
Set-Cookie: __cfduid=d9e1f2908ee4037d46bffa6866549c3151551882776; expires=Thu, 05-Mar-20 14:32:56 GMT; path=/; domain=.example.com; HttpOnly
Location: https://www.example.com/
Server: cloudflare
CF-RAY: 4b350ab9d83fc895-MIA

有人可以帮助我解决这个问题吗?我想念什么?

更新3 >>> nginx.conf中的更多更改和清理cloudflare缓存

Nginx /etc/nginx/nginx.conf

pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {

    log_format formatWithUpstreamLogging '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request';

    #main log format
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                               '$status $body_bytes_sent "$http_referer" '
                               '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log main;
    error_log   /var/log/nginx/error.log;

    server {

      listen 80;

      server_name www.codeonblue.com.br codeonblue.com.br;

       ssl_certificate /etc/letsencrypt/live/codeonblue.com.br/fullchain.pem; # managed by Certbot
       ssl_certificate_key /etc/letsencrypt/live/codeonblue.com.br/privkey.pem;

        # managed by Certbot
       location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass https://localhost:8443/;
       }

    }
}

此更新部分问题解决后:

卷曲测试

curl -I http://www.example.com
HTTP/1.1 200 
Date: Wed, 06 Mar 2019 22:19:11 GMT
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=d3f91ee93c3657a851354dbb4f03741a31551910750; expires=Thu, 05-Mar-20 22:19:10 GMT; path=/; domain=.example.com; HttpOnly
Last-Modified: Wed, 06 Mar 2019 22:03:01 GMT
Accept-Ranges: bytes
Content-Language: en-US
Server: cloudflare
CF-RAY: 4b37b5b08cf05eb2-TPA

在浏览器Firefox / Chrome中,可以看到前端部分,如下图所示:

Firefox

Accessed from Firefox

Chrome

Accessed from Chrome

新问题:

  • 正在使用的证书来自cloudflare,而不是来自certbot(letsencrypt)。 Chrome浏览器认为它不够好,并始终显示为“不安全”。
  • 尚未调用我的应用程序的端点,我还不知道为什么。也许我打错了地址。我应该怎么称呼我的端点?

在访问日志中,我已访问:

  1. curl -I www.example.com.br
  2. 在Firefox中访问http://www.example.com.br
  3. 在Chrome中访问了http://www.example.com.br
  4. 尝试在邮递员中访问我的端点

Nginx访问日志(/var/log/nginx/access.log)

172.68.78.24 - - [06/Mar/2019:22:19:11 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.47.0" "<ip-address-of-my-machine>"

172.68.78.24 - - [06/Mar/2019:22:19:46 +0000] "GET / HTTP/1.1" 200 578 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"
172.68.78.36 - - [06/Mar/2019:22:19:46 +0000] "GET /runtime.js HTTP/1.1" 200 6224 "https://www.example.com/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"
172.68.78.42 - - [06/Mar/2019:22:19:46 +0000] "GET /main.js HTTP/1.1" 200 19198 "https://www.example.com/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"
172.68.78.54 - - [06/Mar/2019:22:19:46 +0000] "GET /styles.js HTTP/1.1" 200 185363 "https://www.example.com/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"
172.68.78.96 - - [06/Mar/2019:22:19:46 +0000] "GET /polyfills.js HTTP/1.1" 200 228524 "https://www.example.com/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"
172.68.78.42 - - [06/Mar/2019:22:19:46 +0000] "GET /vendor.js HTTP/1.1" 200 6821593 "https://www.example.com/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"
172.68.78.18 - - [06/Mar/2019:22:19:48 +0000] "GET /favicon.ico HTTP/1.1" 200 5430 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0" "<ip-address-of-my-machine>"

172.68.78.60 - - [06/Mar/2019:22:20:36 +0000] "GET / HTTP/1.1" 200 578 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "<ip-address-of-my-machine>"
172.68.78.60 - - [06/Mar/2019:22:21:33 +0000] "GET / HTTP/1.1" 200 578 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "<ip-address-of-my-machine>"
172.68.78.60 - - [06/Mar/2019:22:22:06 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "<ip-address-of-my-machine>"
221.229.166.47 - - [06/Mar/2019:22:32:53 +0000] "GET / HTTP/1.1" 200 578 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1" "-"

172.68.78.60 - - [06/Mar/2019:22:44:06 +0000] "GET / HTTP/1.1" 200 578 "-" "PostmanRuntime/7.1.1" "<ip-address-of-my-machine>"

在邮递员中,当我尝试访问端点时:

https://www.example.com:8443/api/cars

在我认为这部分更重要的地方,我得到了很大的收获:

(...)
<title>www.example.com | 522: Connection timed out</title>
(...)
    <h2 class="cf-subheadline">Connection timed out</h2>
(...)
        <span class="cf-status-desc">www.example.com</span>
(...)
        <h2>What happened?</h2>
        <p>The initial connection between Cloudflare's network and the origin web server timed out. As a result, the web page can not be displayed.</p>
                <h5>If you're the owner of this website:</h5>
                   <span>Contact your hosting provider letting them know your web server is not completing requests. An Error 522 means that                         the request was able to connect to your web server, but that the request didn't finish. The most likely cause is that 
                         something on your server is hogging resources.
                   </span>
(...)

我认为超时是由于我访问服务/端点的方式错误。那么,我现在应该如何访问它?如何设置nginx以使用certbot证书而不是cloudflare的证书?

3 个答案:

答案 0 :(得分:0)

我的问题已部分解决。这是我的场景和使用过的配置:

  • 应用程序:Springboot + Angular6(Springboot应用程序在端口 8443 上使用 ssl ,并配置为使用certbot证书)

  • 域解析:CloudFlare(配置为将DNS从我的域解析为云服务器的IP)

  • 云服务器:Amazon Lightsail(运行Nginx和我的应用程序的云中的Linux计算机)

  • Web服务器:Nginx(在Amazon计算机中用于将端口 80 上的http流量重定向到端口 8443 上的https由我的springboot应用程序使用)

Springboot application.properties

server.port=8443
security.require-ssl=true
server.ssl.key-store=/etc/letsencrypt/live/www.example.com/keystore.p12
server.ssl.key-store-password=www.example.com
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=myAlias

Angular 6服务应如何使用API​​

getAll(): Observable<any> {
   return this.http.get('/api/cars');  // production
}

Nginx /etc/nginx/nginx.conf

pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {

    log_format formatWithUpstreamLogging '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request';

    #main log format
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                               '$status $body_bytes_sent "$http_referer" '
                               '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log main;
    error_log   /var/log/nginx/error.log;

    server {

        listen 80;

        server_name www.example.com example.com;

        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
        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass https://localhost:8443/;
                proxy_redirect http://localhost:8443/ https://localhost:8443/;
       }

    }

}

其他设置:

Nginx仍然没有将

http 流量重定向到 https

如果有人知道如何进行此重定向,请告诉我:)

附注:感谢Richard Smith在此问题上的所有帮助和时间!

答案 1 :(得分:0)

我知道这很老了,但我想与其他可能会在本文中发表的人分享我的Nginx配置。

我的整个配置都较大,但是重定向部分如下所示:

server {
    listen 80;

    location / {
        return 301 https://$host:8443$request_uri;
    }
}

基本上,如果您使用Spring提供的服务在HTTPS上提供应用程序,则不需要Proxy pass,ssl_certificate或Nginx上的任何其他内容。当HTTP请求到达端口80时,上面的配置将简单地向浏览器返回301重定向。

答案 2 :(得分:0)

您需要将此添加到您的 server 块中:

# Redirect non-https traffic to https
if ($scheme != "https") {
    return 301 https://$host$request_uri;
}