为什么即使启用了 UFW,我也可以通过 public IP 访问 redis?
Why am I able to access redis over public IP even with UFW enabled?
我分别有 Droplet A 和 Droplet B 运行 Django 和 Redis。他们都在数字海洋的 VPC 上,并且有 public 和私有 IP 地址。
下面是我的redis docker-compose。我正在尝试将容器 redis 端口映射到主机端口,以便我可以通过 VPC 连接到它。
redis:
restart: always
image: redis
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis_data:/data
ports:
- 6379:6379
在 Django 上——也连接到 VPC,我是这样连接到 redis 的:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://private_ip:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
}
}
这有效 - 我能够与我的 redis 液滴进行交互。但是我怀疑 ports: 6379:6379
实际上可能会打开 redis droplet 到互联网,果然,如果我尝试通过 public IP 地址连接,这也有效。即使我在浏览器中输入 Droplet 的 public IP 地址,如下所示:public_ip:6379,我的 Redis 安装将其检测为潜在的安全威胁 - 请求以某种方式通过。我如何阻止所有 http/public 对 redis droplet 的请求,并且只允许通过 VPN 上的私有 ip 进行流量?
这也适用:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://public_ip:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
}
}
更新:
在 Droplet B (redis) 上,这是来自 UFW
的读数
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
然后,如果我将 droplet 的 public IP 地址键入 chrome、public_ip:6379
,我的 docker 读数显示为:
It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.
不仅如此,通过 public IP 地址连接到 redis droplet 真的有效吗?
Docker 和 UFW 之间存在问题。 UFW 不控制 Docker 打开的端口,不幸的是,这种情况也不会显示在 ufw 状态中。有许多建议的解决方案,您可以 google 提出,但我发现对我最有用的是:
https://jorisvergeer.nl/2019/11/03/let-docker-and-ufw-work-nicely/
但是,由于您在 DigitalOcean 上,更简单的方法可能是创建一个 DigitalOcean 防火墙,它只允许授权 IP 在允许的端口访问 Droplet B。设置防火墙后,将 Droplet B 放在里面,这样应该可以很好地控制到 Droplet B 的流量。
我分别有 Droplet A 和 Droplet B 运行 Django 和 Redis。他们都在数字海洋的 VPC 上,并且有 public 和私有 IP 地址。
下面是我的redis docker-compose。我正在尝试将容器 redis 端口映射到主机端口,以便我可以通过 VPC 连接到它。
redis:
restart: always
image: redis
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis_data:/data
ports:
- 6379:6379
在 Django 上——也连接到 VPC,我是这样连接到 redis 的:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://private_ip:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
}
}
这有效 - 我能够与我的 redis 液滴进行交互。但是我怀疑 ports: 6379:6379
实际上可能会打开 redis droplet 到互联网,果然,如果我尝试通过 public IP 地址连接,这也有效。即使我在浏览器中输入 Droplet 的 public IP 地址,如下所示:public_ip:6379,我的 Redis 安装将其检测为潜在的安全威胁 - 请求以某种方式通过。我如何阻止所有 http/public 对 redis droplet 的请求,并且只允许通过 VPN 上的私有 ip 进行流量?
这也适用:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://public_ip:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
}
}
更新: 在 Droplet B (redis) 上,这是来自 UFW
的读数To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
然后,如果我将 droplet 的 public IP 地址键入 chrome、public_ip:6379
,我的 docker 读数显示为:
It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.
不仅如此,通过 public IP 地址连接到 redis droplet 真的有效吗?
Docker 和 UFW 之间存在问题。 UFW 不控制 Docker 打开的端口,不幸的是,这种情况也不会显示在 ufw 状态中。有许多建议的解决方案,您可以 google 提出,但我发现对我最有用的是:
https://jorisvergeer.nl/2019/11/03/let-docker-and-ufw-work-nicely/
但是,由于您在 DigitalOcean 上,更简单的方法可能是创建一个 DigitalOcean 防火墙,它只允许授权 IP 在允许的端口访问 Droplet B。设置防火墙后,将 Droplet B 放在里面,这样应该可以很好地控制到 Droplet B 的流量。