如何为 Synology 驱动器设置 nginx 反向代理?

如何为 Synology 驱动器设置 nginx 反向代理?

总结

我尝试设置 nginx 以通过 6690 将 TCP 连接转发到 Synology Drive。但是使用listen 6690 ssl;Synology Drive Client 时找不到 NAS,使用listen 6690;(不使用 SSL)时可以找到 NAS,但会使用其未签名的证书,而不是使用 nginx 存储的证书。知道如何启用 SSL 并将 nginx 反向代理与 Synology Drive 一起使用吗?

介绍

我已经找到了几篇帖子/问题,解释了如何使用 nginx 作为另一台计算机上的反向代理来设置与 Synology NAS 的 SSL 连接。因此,当访问 (https://)my-domain.com 时,我(已经)可以访问我的 Synology Drive 的设置网站(即可通过端口 5000/5001 访问的 DSM)。但是,我也想设置 Synology Drive 以使用来自 Let's Encrypt 的相同 SSL 证书,但在这里我在设置 nginx 时遇到了困难。

问题

因此,我只想配置 Synology Drive,并设置 drive.my-domain.com 的 DNS 以访问我的路由器。此外,我为该域获取了 SSL 证书,并将 Synology Drive HTTPS 端口调整为 10003。在我的路由器中,我按照建议将端口 80、443 和 6690 转发到我的反向代理这里。对于 nginx,我配置了/etc/nginx/conf.d/synology.conf

include /etc/letsencrypt/options-ssl-nginx.conf;

server {
    listen      80;
    server_name drive.my-domain.com default_server;

    # For Let's Encrypt verification
    location ^~ /.well-known {
        allow all;
        root /data/letsencrypt/;
    }
}

server {
    listen 80;
    listen 443 ssl;
    server_name drive.my-domain.com;

    location / {
        proxy_set_header    Host $host;
        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_pass          https://<IP-OF-SYNOLOGY-NAS>:10003;
        proxy_read_timeout  90;
    }

    ssl_certificate         /etc/letsencrypt/live/drive.my-domain.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/drive.my-domain.com/privkey.pem;
    
    include /etc/letsencrypt/options-ssl-nginx.conf;
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}

此外,我添加了以下行/etc/nginx/nginx.conf

...

include /etc/nginx/fallthrough.conf;

/etc/nginx/fallthrough.conf包含以下内容:

stream {

    upstream synology_drive {
         server <IP-OF-SYNOLOGY-NAS>:6690;
    }

    server {
        listen     6690 ssl;
        proxy_pass synology_drive;
        
        ssl_certificate     /etc/letsencrypt/live/drive.my-domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/drive.my-domain.com/privkey.pem;
    }
}

但是,尝试设置 Synology Drive Client 时,它无法连接/找到 Synology NAS。当更改/etc/nginx/fallthrough.conf为不使用 SSL 时,即:

stream {

    upstream synology_drive {
         server <IP-OF-SYNOLOGY-NAS>:6690;
    }

    server {
        listen     6690;
        proxy_pass synology_drive;
    }
}

找到了 Synology NAS,但使用的是 NAS 上存储的自签名证书,而不是反向代理计算机上存储的 Let's Encrypt 证书。

有人知道我在这里做什么或者可能做错了什么吗?

答案1

stream模块是第 4 层代理模块,也就是说,它仅在连接客户端和代理服务器之间转发 TCP 数据包。

由于 TLS 发生在更高级别,因此 nginx 不参与 SSL 加密。我实际上很惊讶 nginx 不会对ssl_certificate您的配置中的指令给出任何错误。

您唯一的选择是将私钥和证书从 nginx 复制到 Synology 设备,因为在这种情况下,它是终止 TLS 连接的实体。

答案2

最近,我在尝试为桌面客户端在 Synology Drive 前提供由 LetsEncrypt 提供支持的 SSL 代理时也遇到了这类问题。

我认为核心问题在于 Synology Drive TCP 6690 是一种专有协议,它以未加密的形式开始,然后根据要求进行自己的 SSL 握手。

直接查询我的 NAS 显示最初没有可用的 SSL 信息:

$ openssl s_client -connect localhost:6690 < /dev/null 
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 293 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

因此,当我配置socat坐在我的 NAS 前面并使用 LetsEncrypt 证书时:

$ socat -ddd -v OPENSSL-LISTEN:6690,reuseaddr,fork,su=nobody,key=/data/cert/key.pem,cert=/data/cert/cert.pem,cafile=/data/cert/fullchain.pem TCP:synology.local:6690
2023/08/28 04:44:41 socat[7] I setting option "so-reuseaddr" to 1
2023/08/28 04:44:41 socat[7] I setting option "fork" to 1
2023/08/28 04:44:41 socat[7] I setting option "substuser" to 65534
2023/08/28 04:44:41 socat[7] I setting option "openssl-key" to "/data/cert/key.pem"
2023/08/28 04:44:41 socat[7] I setting option "openssl-certificate" to "/data/cert/cert.pem"
2023/08/28 04:44:41 socat[7] I setting option "openssl-cafile" to "/data/cert/fullchain.pem"
2023/08/28 04:44:41 socat[7] I setting option "openssl-min-proto-version" to "TLS1.3"
2023/08/28 04:44:41 socat[7] I SSL_CTX mode has SSL_MODE_AUTO_RETRY set. Correcting..
2023/08/28 04:44:41 socat[7] I PEM_read_bio_DHparams(0x7f70f108bd90, NULL, NULL, NULL): error
2023/08/28 04:44:41 socat[7] I socket(2, 1, 6) -> 6
2023/08/28 04:44:41 socat[7] I starting accept loop
2023/08/28 04:44:41 socat[7] N listening on AF=2 0.0.0.0:6690

我可以通过以下方式成功进行交互openssl

$ openssl s_client -connect drive.example.com:6690 < /dev/null
CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = drive.example.com
verify return:1
---
Certificate chain
 0 s:CN = drive.example.com
   i:C = US, O = Let's Encrypt, CN = R3
   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
   v:NotBefore: Aug 27 21:41:59 2023 GMT; NotAfter: Nov 25 21:41:58 2023 GMT
 1 s:C = US, O = Let's Encrypt, CN = R3
   i:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Sep  4 00:00:00 2020 GMT; NotAfter: Sep 15 16:00:00 2025 GMT
 2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1
   i:O = Digital Signature Trust Co., CN = DST Root CA X3
   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jan 20 19:14:03 2021 GMT; NotAfter: Sep 30 18:14:03 2024 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
REDACTED
-----END CERTIFICATE-----
subject=CN = drive.example.com
issuer=C = US, O = Let's Encrypt, CN = R3
---
No client certificate CA names sent
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 5241 bytes and written 797 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 4096 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
DONE

从 Synology Drive 桌面客户端连接时出现版本号错误:

2023/08/28 04:48:51 socat[7] I accept(6, {2, AF=2 192.168.10.210:58099}, 16) -> 7
2023/08/28 04:48:51 socat[7] N accepting connection from AF=2 192.168.10.210:58099 on AF=2 172.17.0.2:6690
2023/08/28 04:48:51 socat[7] I permitting connection from AF=2 192.168.10.210:58099
2023/08/28 04:48:51 socat[7] N forked off child process 9
2023/08/28 04:48:51 socat[7] I close(7)
2023/08/28 04:48:51 socat[7] I still listening
2023/08/28 04:48:51 socat[7] N listening on AF=2 0.0.0.0:6690
2023/08/28 04:48:51 socat[9] I just born: child process 9
2023/08/28 04:48:51 socat[9] I close(4)
2023/08/28 04:48:51 socat[9] I close(3)
2023/08/28 04:48:51 socat[9] I just born: child process 9
2023/08/28 04:48:51 socat[9] I close(6)
2023/08/28 04:48:51 socat[9] E SSL_accept(): error:0A00010B:SSL routines::wrong version number
2023/08/28 04:48:51 socat[9] N exit(1)
2023/08/28 04:48:51 socat[9] I close(7)
2023/08/28 04:48:51 socat[7] N childdied(): handling signal 17
2023/08/28 04:48:51 socat[7] I childdied(signum=17)
2023/08/28 04:48:51 socat[7] I childdied(17): cannot identify child 9
2023/08/28 04:48:51 socat[7] I waitpid(): child 9 exited with status 1
2023/08/28 04:48:51 socat[7] I waitpid(-1, {}, WNOHANG): No child process
2023/08/28 04:48:51 socat[7] I childdied() finished

假设我使用socat不正确,我尝试了另一个支持 SSL 的通用套接字工具(ghostunnel),它也报告了来自 Synology Drive 客户端的无效握手:

[183] 2023/08/28 05:15:56.268946 error on TLS handshake from 192.168.10.210:58297: tls: first record does not look like a TLS handshake

我认为 Synology Drive 客户端最初以非 SSL 形式发送一些消息,然后稍后可以升级为 SSL,这会破坏标准的支持 SSL 的套接字握手过程。

如果这是真的,那么 LetsEncrypt 证书和密钥似乎应该存在于 Synology NAS 本身上,这样它可以加强与签名文件的连接。

相关内容