我有客户端连接到我的 WebSockets 游戏服务器以进行在线浏览器游戏。游戏服务器是在玩家开始游戏时创建和销毁的,因此每个服务器都可以有一个我无法控制的不同 IP 地址。
我需要 WebSockets 是安全的(WSS),所以我有一个带有 SSL 证书的 nginx 代理。客户端收到游戏服务器的 IP,但不是直接连接(不安全),而是通过我的 nginx 服务器将游戏服务器 IP 作为查询参数。
问题是:现在任何人都可以使用我的 nginx 服务器代理他们选择的任何 IP。我需要的是一种确保 nginx 仅代理到我的游戏服务器的方法。
我无法控制游戏服务器 IP,因为它是外部主机,但我拥有游戏服务器代码。我的 nginx 代理由我托管,但游戏服务器由提供商托管。
我的计划是在游戏服务器和 Nginx 上拥有一个共享密钥并用它加密所有流量,但我正在努力找出如何做到这一点。
这是我到目前为止所做的(基于这个要点):
我创建了自己的自签名 CA 证书:
openssl genrsa -des3 -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt
我为游戏服务器创建了一个证书:
openssl genrsa -out gameserver.key 2048
openssl req -new -key gameserver.key -out gameserver.csr
openssl x509 -req -in gameserver.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out gameserver.crt -days 500 -sha256
我对 nginx 服务器做了同样的事情(这需要吗?注意:不需要):
openssl genrsa -out nginx.key 2048
openssl req -new -key nginx.key -out nginx.csr
openssl x509 -req -in nginx.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out nginx.crt -days 500 -sha256
我的 nginx 配置是这样的:
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
# these are for game client
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
location / {
if ( $arg_host != "" ) {
proxy_pass https://$arg_host:$arg_port;
}
proxy_ssl_certificate nginx.crt;
proxy_ssl_certificate_key nginx.key;
proxy_ssl_trusted_certificate rootCA.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}
}
我的游戏服务器是一个 WebSockets 服务器,使用gameserver.key
和gameserver.csr
.
但是,当我尝试它时,nginx 错误日志显示:
upstream SSL certificate verify error: (18:self signed certificate) while SSL handshaking to upstream
我不确定这是否可行,我哪里出错了?我发现唯一提到此错误的文章表明游戏服务器证书不受信任,但我不知道为什么。
我也不确定Common Name
在创建证书时我应该赋予什么价值(因为每个游戏服务器都在自己的 IP 上)以及这是否是一个问题。
我建议为后端设置一个内部证书颁发机构,并要求您的后端可以通过该证书颁发机构进行验证,您可以引导这些证书以包含其 IP 或使用通用主机名覆盖 IP(我认为会够了)。