Day25-你的资料安全吗(三)

前言

因为资料库基本上可以分成 SQL 跟 NoSQL 两大类,昨天讲完 SQL injection 之後今天该来讲一讲 NoSQL 的安全性了。但因为 NoSQL 又分成 Document-based(如 MongoDB)、Key-value(如 Redis)、Graph(如 Neo4J) 等等很多种,不太可能全部讲过一遍,所以今天就拿最常被使用的 MongoDB 来说说

Access Control

如果先前没有用过 MongoDB 的话,一开始最容易犯的错就是在启动 Mongo Server 时没有加上 --auth 把 Access Control 开起来,而是直接用 mongod --port <port> 来启动

这样一来即便你有做到像前天说的权限管理、根据权限需求划分成不同的 user,但因为没有启动 Access Control,任何人都可以不需要帐号密码就可以登入资料库,并对你的资料库进行任何操作,所以可能会造成非常严重的後果

那除了在启动 MongoDB 时加上 --auth 之外,还有没有什麽其他比较方便的方法可以启用 Access Control 呢?答案就是在 /etc/mongod.conf 里面直接把 Authentication 开起来,如此一来就不用担心启动时忘记下 --auth,反正 mongod 在启动时会自动去读设定档

Security:
    Authentication: on

但如果你不是自己下 mongod 指令,而是用官方的 Docker image 来启动 MongoDB。因为启动 Access Control 已经是 Mongo 的 best practice 了,所以在使用官方的 image 时,只要你把 root user 的帐号密码设定好,Mongo 就会自动把 Access Control 开起来然後建立好 root user,你只需要用 root user 登入後再根据需求新增其他低权限的 user 就好了(非常不建议直接把 root user 拿来用)

services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

不要用预设的 port

如果没有特别设定的话,预设情况下 MongoDB 开起来就是在 27017 port,也因为这样,很多骇客在网路上乱扫别人的资料库时都会顺便扫一下 27017,如果你一时大意帐号密码设得比较简单,或是根本就忘记开启 Access Control,那骇客就可以轻易进入你的资料库胡搞瞎搞

而要改 port 其实也很简单,只要在启动 mongod 时加上 --port <port> 来指定想要的 port 就好了,如果你比较懒的话,也可以到 /etc/mongod.conf 里面加上 port 设定,那在启动时就不会忘记之前开在哪个 port

net:
    port: 12345

如果你是用 Docker 的话,因为 docker-compose 可以直接在 yml 里面设定 port binding,所以只要直接把外部的任何一个 port bind 到 container 内部的 27017 就好了,完全不需要动 mongod 本身的设定

services:
  mongo:
    image: mongo
    restart: always
    ports:
      - "12345:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

阻挡外部连线

大部分时候,我们的资料库上了云端之後几乎只有应用程序会直接存取他,所以比起让任何人都可以从外部接触到资料库,不如就听在某几个特定的 IP 就好了,一种白名单的概念

譬如说我希望只有自己跟同一个子网路的机器可以连进来,那就可以只监听 127.0.0.1192.168.128.1 这两个 IP 位址,如此一来外部的骇客就没办法直接接触到资料库,虽然这也代表想在自己电脑上查 DB 时就需要先 ssh 上机器再连进 127.0.0.1,但其实现在大部分 MongoDB 的 GUI client 也都支援这功能了,只要简单设定一下 ssh key 让他自动连进去就好了,所以还是非常推荐这种做法

net:
    bindIp: 127.0.0.1, 192.168.128.1

而 Docker 的话也很简单,只要你在 docker-compose.yml 里面设定一下想要 bind 到哪个 IP 就好了,譬如说下面的设定档就是只监听 127.0.0.1192.168.128.1 这两个 IP 位址的 12345 port,也是完全不需要动到 MongoDB 里面的设定,所以哪天想改就改非常有弹性

services:
  mongo:
    image: mongo
    restart: always
    ports:
      - "127.0.0.1:12345:27017"
      - "192.168.128.1:12345:27017"

小结

MongoDB 身为最热门的 NoSQL 资料库之一,如果不花点时间搞懂他的设定的话一不小心就可能会让资料库暴露在危险之中,尤其是 mongod 在启动时不会自动加上 --auth 简直是智障到不行,据我所知每年都有不少这类忘记开 Access Control 的 MongoDB 被攻击,真心觉得应该要预设开启 --auth,如果不想要的话才手动下指令 mongod --no-auth 才对

今天已经是资料库安全的第三天了,跟资料库相关的内容就到这,如果对於这几天的内容有问题的话欢迎在下方留言,我很乐意大家讨论讨论,都没问题的话明天就要来讲近年来大容器时代的霸主 Docker 了~


<<:  Day27 - 如何让 Google 搜寻到你的网站

>>:  [DAY26]资料库的CRUD

Day6 - 读 Concurrency is not Parallelism - Rob Pike (一)

本篇是看 Concurrency is not Parallelism 的心得 Concurrenc...

MyBatis 实际测试

MyBatis 实际测试 ...

[Day19]-档案读取与写入

写入档案 写入空文件内 档案很大时分段写入 Shutil模组 档案或目录的复制、移动、更改和删除,...

[Day6] 学 Bootstrap 是为了走更长远的路 ~ Grid 篇 (1)

前言 今天终於来到本系列文第一个重头戏, 也是 Bootstrap 非常实用的~~~~~ Grid ...

[Day6] Ajax Type Ahead

[Day6] Ajax Type Ahead 输入框筛选器制作 需要用到的技巧与练习目标 fetch...