V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wmui
V2EX  ›  问与答

免费的 https 证书可以不监控 443 端口吗

  •  
  •   wmui · 2018-12-21 09:48:14 +08:00 · 10281 次点击
    这是一个创建于 2183 天前的主题,其中的信息可能已经有所发展或是发生改变。

    事情是这样的,我在腾讯云申请了两个免费的 https 证书, 分别针对 www.example.comapi.example.com ,但是证书只能 listen 443 端口,如果修改了端口就会导致回源失败,我也不知道回源失败什么意思,反正就是证书不能用。服务器有一个独立 IP,想对两个子域名都部署 https,如何做比较好呢,希望了解的朋友能帮助一下,感谢

    配置文件大概是这样的:

    upstream api {
        server 127.0.0.1:3010;
    }
    server {
      server_name api.example.wang;
      if ($scheme = http) {
        rewrite ^(.*) https://$host$1 permanent;
      }
    }
    server {
        listen 443;
        server_name api.example.wang;
        ssl on;
        ssl_certificate /root/ssl/1_api.example.wang_bundle.crt;
        ssl_certificate_key /root/ssl/2_api.example.wang.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        if ($ssl_protocol = "") {
        rewrite ^(.*) https://$host$1 permanent;
        }
    
        location / {
            proxy_set_header Host  $http_host;
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header X-Nginx-proxy true;
            proxy_pass http://api;
            proxy_redirect off;
        }
    }
    
    23 条回复    2018-12-21 18:10:51 +08:00
    meik2333
        1
    meik2333  
       2018-12-21 09:53:52 +08:00
    你可以通过 Nginx 把同一个端口的请求分到不同的服务上。
    meik2333
        2
    meik2333  
       2018-12-21 09:57:02 +08:00
    server {
    listen 443;
    server_name api.example.com;
    ......
    }
    server {
    listen 443;
    server_name www.example.com;
    ......
    }

    大概这样
    meik2333
        3
    meik2333  
       2018-12-21 09:58:14 +08:00
    还有你们是怎么做到代码格式化和高亮的。。。我每次都挤成一坨了。。。
    b1gCi
        4
    b1gCi  
       2018-12-21 09:58:21 +08:00
    server 可以定义多个,都监听 443 端口没问题,只要 server_name 设置成不同的子域名就行
    ysc3839
        5
    ysc3839  
       2018-12-21 10:07:09 +08:00 via Android   ❤️ 1
    @meik2333 主题里面可以使用 Markdown,有代码块的语法。
    例如这样
    ```
    Code
    ```
    ipwx
        6
    ipwx  
       2018-12-21 10:12:47 +08:00   ❤️ 1
    @meik2333 回帖不支持,需要用 gist
    meik2333
        7
    meik2333  
       2018-12-21 10:14:36 +08:00
    @ysc3839
    @ipwx
    多谢
    wmui
        8
    wmui  
    OP
       2018-12-21 10:17:24 +08:00
    @meik2333 @b1gCi 我之前也是这种思路, 方法是可行的,但是会有一个问题:如果在服务器上执行 http 请求,既 www.example.comapi.example.com 发送请求,由于是同一个端口,会导致请求超时。我向其他第三方接口发送请求就不会超时,所以 http 我监听了不同的端口,分别是 3000 和 3010,https 感觉是不是也要监听不同的端口?
    ysc3839
        9
    ysc3839  
       2018-12-21 10:17:26 +08:00 via Android
    不知道你这是什么问题,不过你的配置文件可能有点问题。
    http 跳转 https 应该配置两个 server,一个是 80 端口的 http,一个是 443 端口的 https。跳转也不应该使用 rewrite,应该使用 return 301。
    可以这样写
    ```
    server {
    listen 80;

    server_name www.example.com;
    server_name api.example.com;

    return 301 https://$host$request_uri;
    }
    ```
    b1gCi
        10
    b1gCi  
       2018-12-21 11:02:17 +08:00
    @wmui 超时好像和这个无关,另外 https://nginxconfig.io/可以尝试一下
    wmui
        11
    wmui  
    OP
       2018-12-21 11:10:18 +08:00
    @ysc3839 我把 http 统一监听 80,https 统一监听 443,可以通过不同域名代理不同的端口服务。但是仍然存在超时问题,错误信息 GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:67:26) ,应该和 DNS 有关,我在排查下原因,多谢帮助
    wmui
        12
    wmui  
    OP
       2018-12-21 11:16:06 +08:00
    贴一下测试代码:

    ```js
    const express = require('express')
    const app = express()
    const axios = require('axios')

    app.get('/v1', async function(req, res, next){
    const { data } = await axios.get('https://api.example.com/test')
    res.send(data)
    })

    app.listen(3000)
    ```

    访问 https://www.example.com/v1,服务器向 https://api.example.com/test 发送 http 请求,网络超时。如果 api 地址换成非本机地址,就不会有超时问题
    sarices
        13
    sarices  
       2018-12-21 11:23:13 +08:00
    加多一个
    server {
    listen 443;
    listen 80;
    server_name www.example.wang;
    ssl on;
    ssl_certificate /root/ssl/1_www.example.wang_bundle.crt;
    ssl_certificate_key /root/ssl/2_www.example.wang.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    if ($server_port !~ 443){
    rewrite ^(/.*)$ https://$host$1 permanent;
    }
    #后面自己写
    }
    zhucegeqiu
        14
    zhucegeqiu  
       2018-12-21 11:25:39 +08:00
    caddy 自动申请的 Let's Encrypt 免费证书,dns 验证方式,随便什么端口都可以,家里本来 80/443 也没法用
    tdtdttdd
        15
    tdtdttdd  
       2018-12-21 11:31:29 +08:00 via Android
    因为 https 只会监听 443,其他端口不行
    momocraft
        16
    momocraft  
       2018-12-21 11:34:35 +08:00
    ssl 证书就没有限制端口,显然不是“证书不能用”是别的什么不能用

    两个主机名同在 443 对于近代的(有 SNI 的)客户端不应该有问题
    Dk2014
        17
    Dk2014  
       2018-12-21 11:57:38 +08:00 via Android
    两个证书就两个 server
    另外你强制 https 不需要再开一个 server,下面那个再加个监听 80+跳转就行了
    listen 80;
    if ($ssl_protocol = "") { return 301 https://$host$request_uri; }
    免费证书的话,你还可以用 acme 签泛域名证书
    wmui
        18
    wmui  
    OP
       2018-12-21 12:11:23 +08:00
    @Dk2014 @momocraft @sarices 大家的配置方法是可行的,两个子域名都能使用 https,最要的问题是当我在服务器端发送 http 请求时,网络超时,并提示 dns 错误。如果是浏览器发送请求就没这个问题

    测试网址: https://www.86886.wang, 大家可以看下,现在是浏览器发送请求,没有问题
    Techzero
        19
    Techzero  
       2018-12-21 12:13:10 +08:00 via Android
    证书跟端口没关系,只跟域名有关
    ysc3839
        20
    ysc3839  
       2018-12-21 13:53:01 +08:00 via Android   ❤️ 1
    @sarices @Dk2014
    按照 nginx 官方的说法,rewrite 是不好的做法。
    https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites

    至于使用 if 还是多一个 server block,似乎没找到相关的解释。
    搜索到了这个回答 https://serverfault.com/a/474345
    他说 using "rewrite" or "if ssl_protocol" etc is slower and worse. 但没说明理由。

    我自己的做法是使用单独的 server block。
    wmui
        21
    wmui  
    OP
       2018-12-21 16:42:16 +08:00
    问题解决了,hosts 文件中增加两条记录,把 127.0.0.1 解析到对应的子域名就可以了,我也不清楚为什么这样做就不超时了
    behanga
        22
    behanga  
       2018-12-21 17:17:03 +08:00
    了解一下 Nginx 反向代理. request 到 443 端口后,用 Nginx 转发到其他端口,本身设计上就应该是对外是 443,对内不知道具体端口是哪个
    wmui
        23
    wmui  
    OP
       2018-12-21 18:10:51 +08:00 via Android
    @behanga 嗯,已经准备系统的学习下 nginx 和 http 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   884 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:49 · PVG 04:49 · LAX 12:49 · JFK 15:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.