V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
siagasky
V2EX  ›  分享发现

VPS 上多个 web server 配置 ssl

  •  
  •   siagasky · 2017-11-05 15:47:28 +08:00 · 2460 次点击
    这是一个创建于 2582 天前的主题,其中的信息可能已经有所发展或是发生改变。

    69714126.jpg

    本文探讨了如何为同一个 VPS 上使用不同端口的 web 应用配置 https。

    背景

    我在自己的一台 VPS 上部署了多个 web 应用,包括 commafeed,leanote,h5ai,还有 webdav 应用等等。这些应用监听的端口不同,可以通过域名+端口的形式访问。但是这样的访问形式显然不够简洁。另外在全民https的现在,还通过这样的形式访问网站太落伍了。因此,我在网上做了一些搜索,主要参考下列文章:

    经过对自己 nginx 配置文件的一番魔改,目前实现的情形如下:

    • 可以通过 https 访问二级域名,若通过 http 访问会跳转到 https
    • 直接访问域名+端口会出错

    未解决的问题是

    • 还是可以通过ip+端口访问

    在 Cloudflare 上的配置

    1. 修改域名的 Nameserver 为 Cloudflare 提供的 Nameserver
    2. 在 Cloudflare 的 DNS 选项下添加自己所需的二级域名的 A 记录,并开启 CDN。

    1. 在 Crypto 选项下将 SSL 选项修改Full,之后 Cloudflare 就会开始给你分配证书,可能要等挺久的,然后再将下面的 Always use https 选项打开。
    2. 在 Page Rules 选项下添加 Rule,比如我想要我的所有二级域名都自动跳转到 https

    至此,需要在 cloudflare 上配置的地方就结束了。

    在 VPS 上的配置

    生成自签名的 ssl 证书

    1. 安装 openssl,例如我用的 archlinux
    pacman -S openssl
    
    1. 签发证书 (以下内容完全来自用自签名 SSL 证书配合 CloudFlare 免费 SSL 构建全站 HTTPS 加密)
    mkdir -p <DIR>/cert //建立制作存放证书的目录
    cd  <DIR>/cert
    # 签发一个根域名的 CA 证书
    openssl genrsa -des3 -out ca.key 2048 //创建一个私钥 ca.key
    openssl req -new -x509 -days 7305 -key ca.key -out ca.crt //生成 CA 根证书(公钥)
    # 其中 days 后面的参数是有效期。执行后会让你填相关信息,common name 填根域名,即 yourdomain.com
    openssl genrsa -des3 -out yourdomain.com.pem 1024 //生成一个给泛域名用的私钥
    openssl rsa -in yourdomain.com.pem -out yourdomain.com.key //解密私钥
    openssl req -new -key yourdomain.com.pem -out yourdomain.com.csr //生成签名请求
    # 这一步中的 common name 填入泛域名,即*.yourdomain.com ,这样生成的证书可以供所有子域名使用
    vi /etc/openssl.cnf
    # 这里修改 dir = 的值为./ca
    mkdir -p ca/newcerts
    touch ca/index.txt
    touch ca/serial
    echo "01" > ca/serial
    openssl ca -policy policy_anything -days 7305 -cert ca.crt -keyfile ca.key -in yourdomain.com.csr -out yourdomain.com.crt //执行签名
    cat ca.crt >> yourdomain.com.crt //把 ca.crt 中的内容粘贴到 yourdomain.com.crt 的最后,证书签发完成
    

    配置 nginx

    1. 安装 nginx
    pacman -S nginx-mainline
    
    1. 魔改 nginx,这里贴上自己的配置,写的很垃圾,大家明白意思就行,主要就是使用多个 server 块。
    # 前面的配置参考了 cloudflare 和 Mozilla 推荐的配置
    ssl_protocols               SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ecdh_curve              X25519:P-256:P-384:P-224:P-521;
    ssl_ciphers                 "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECD$
    ssl_prefer_server_ciphers   on;
    ssl_certificate <DIR>/cert/yourdomain.crt;
    ssl_certificate_key <DIR>/cert/yourdomain.key;
    
    server {
        listen 443 ssl http2;
        server_name note.yourdomain;
        location / {
            proxy_pass http://127.0.0.1:port1/;    //通过 https://note.yourdomain 访问我的 leanote
        }
        }
    
    server {
        listen 443 ssl http2;
        server_name rss.yourdomain ;
        location / {
            proxy_pass http://127.0.0.1:port2/;  //通过 https://rss.yourdomain 访问我的 commafeed
        }
        }
    
    server {
        listen 443 ssl http2;
        server_name file.yourdomain;
        location / {
            proxy_pass http://127.0.0.1:port3/; //通过 https://file.yourdomain 访问我的 h5ai
        }
        location /webdav {
            proxy_pass http://127.0.0.1:port4/; //通过 https://file.yourdomain/webdav 访问我的 webdav
        }
        location /zotero {
            proxy_pass http://127.0.0.1:port5/; //通过 https://file.yourdomain/zotero 访问我的另一个 webdav
        }
        }
    }
    

    一些坑

    1. 在 cloudflare 上的证书生效之前网站会无法访问,chrome 报错ERR_SSL_VERSION_OR_CIPHER_MISMATCH

    本文地址 https://blog.liuwm.work/2017/11/05/VPS 上多个 web-server 配置 ssl/

    8 条回复    2017-11-06 12:16:16 +08:00
    xfspace
        1
    xfspace  
       2017-11-05 15:52:48 +08:00 via Android
    啥意思?
    V2EX 不支持全文转载吧。
    Marfal
        2
    Marfal  
       2017-11-05 16:15:35 +08:00 via Android
    这也能叫魔改。
    siagasky
        3
    siagasky  
    OP
       2017-11-05 16:18:14 +08:00
    @Marfal 我是瞎 jb 改的意思···
    kmahyyg
        4
    kmahyyg  
       2017-11-05 17:41:39 +08:00 via Android
    没意思,直接 le + crontab 搞定
    boboliu
        5
    boboliu  
       2017-11-05 17:49:29 +08:00 via Android
    1. 既然都有 cf 了上啥 full,flexible 岂不美哉。。。
    2. service 监听本地或者防火墙禁止外部访问端口就能解决问题了。

    结论:楼主还需要学习一个
    shiji
        6
    shiji  
       2017-11-05 17:51:38 +08:00 via Android
    我不知道说点啥。
    msg7086
        7
    msg7086  
       2017-11-05 18:17:25 +08:00 via Android
    下意识看了发帖时间,看完以后不知道说点啥。
    edsheeran
        8
    edsheeran  
       2017-11-06 12:16:16 +08:00 via iPhone
    都 cf 了,server 還配個毛
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1095 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 23:42 · PVG 07:42 · LAX 15:42 · JFK 18:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.