背景:
因为postgresql或者mysql目前通过docker安装,只需要输入主机IP、用户名、密码即可访问成功,这样其实是不安全的,可能会通过一些手段获取到用户名密码导致数据被窃取。而ES、kafka等也是通过用户名/密码方式连接,但是这些数据重要性相比较于数据库要低一些,毕竟都是一些日志以及消息而已。
解决方案:
通过开启SSL证书认证的方式加强防护,配合使用防火墙策略白名单方式、增加密码复杂度。本文档主要是介绍开启SSL认证方式。
具体实施步骤:
一、创建目录存储配置信息
1、mkdir /postgre
2、进入 文件夹
cd postgre
3、创建目录
mkdir certs
4、创建目录
mkdir data
二、创建Openssl配置文件
1、进入cd /postgre/certs 目录
2、执行 touch openssl.cnf
3、修改文件
vim openssl.cnf
4、将下面信息粘贴至文件中
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
C = CN
ST = Beijing
L = Beijing
O = MyOrg
OU = IT
CN = postgres
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
IP.1 = 192.168.2.1 #数据库主机地址
DNS.1 = postgres #数据库用户名
如下图:
三、创建SSL证书生成脚本generate_certs.sh
1、进入 cd /postgre/certs 目录
2、touch generate_certs.sh
3、vim generate_certs.sh
4、将下面信息粘贴至文件中
#!/bin/bash
ROOT_KEY="root.key"
ROOT_CRT="root.crt"
SERVER_KEY="server.key"
SERVER_CSR="server.csr"
SERVER_CRT="server.crt"
DAYS=365
BITS=2048
echo "生成根私钥..."
openssl genpkey -algorithm RSA -out "$ROOT_KEY"
echo "生成根证书..."
openssl req -x509 -new -nodes -key "$ROOT_KEY" -sha256 -days "$DAYS" -out "$ROOT_CRT" -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Root CA/OU=IT Department/CN=postgres"
echo "生成服务器私钥..."
openssl genpkey -algorithm RSA -out "$SERVER_KEY"
echo "生成证书签名请求 (CSR)..."
openssl req -new -key "$SERVER_KEY" -out "$SERVER_CSR" -config openssl.cnf
echo "使用根证书签署服务器证书..."
openssl x509 -req -in "$SERVER_CSR" -CA "$ROOT_CRT" -CAkey "$ROOT_KEY" -CAcreateserial -out "$SERVER_CRT" -days 365 -extfile openssl.cnf
echo "验证服务器证书..."
openssl verify -CAfile "$ROOT_CRT" "$SERVER_CRT"
echo "生成完成!以下是生成的文件:"
ls -l "$ROOT_KEY" "$ROOT_CRT" "$SERVER_KEY" "$SERVER_CSR" "$SERVER_CRT"
如图:
四、创建配置证书目录以及生成证书
1、执行cd /postgre/certs
2、执行sh generate_certs.sh 运行该脚本
3、如下图代表生成成功
4、查看生成的证书
五、为证书目录赋权限,以便postgre容器可以访问执行这些证书
1、cd /postgre
2、chmod 777 certs
3、chmod 777 data
2、chown 999:999 certs/* 之所以所属用户/组设置为999 是因为postgre默认进程所属就是999。
3、chmod 600 certs/* 为证书目录设置为所属用户可读可写,如果权限过大会在连接数据库时报错!
六、创建配置文件postgresql.conf
1、进入 cd /postgre
2、执行 touch postgresql.conf 命令
3、执行 vim postgresql.conf 命令
4、复制如下配置信息到文件中
ssl = on #开启SSL认证
ssl_cert_file = '/var/lib/postgresql/certs/server.crt' #服务器证书路径
ssl_key_file = '/var/lib/postgresql/certs/server.key' #密钥路径
ssl_ca_file = '/var/lib/postgresql/certs/root.crt' #根证书路径
listen_addresses = '*' #监听所有
ssl_min_protocol_version = 'TLSv1.2' #SSL等级最小为1.2
logging_collector = on # 开启日志
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d # 日志文件保留一天后轮换
log_rotation_size = 10MB # 当日志文件达到10MB时轮换
log_min_messages = debug # 记录警告级别及以上的消息
log_connections = on # 记录连接尝试
log_disconnections = on # 记录断开连接
如下图
七、创建配置文件pg_hba.conf
1、cd /postgre
1、执行 touch pg_hba.conf 命令
2、执行 vim pg_hba.conf 命令
3、复制如下配置信息到文件中
hostssl all all 0.0.0.0/0 cert clientcert=1
如下图
八、安装并启动PostgreSQl
1、安装postgreSQL 13.3版本
镜像会提供给运维。
2、启动postgreSQL容器
docker run -d --name my-postgres-ssl -p 5432:5432 -e POSTGRES_PASSWORD=xxxx -v /postgre/postgresql.conf:/etc/postgresql/postgresql.conf -v /postgre/certs:/var/lib/postgresql/certs -v /postgre/data:/var/lib/postgresql/data b2fcd079c1d4 -c 'config_file=/etc/postgresql/postgresql.conf'
其中 -e POSTGRES_PASSWORD=password 为数据库设置密码为 “password” 默认用户名为 “postgres”
其中 -v /postgre/postgresql.conf:/etc/postgresql/postgresql.conf 将宿主机的配置文件挂载到容器中。
其中 -v /postgre/certs:/var/lib/postgresql/certs 为数据库映射证书目录 将宿主机中的证书目录挂载到容器中 前面为宿主机目录 后面为容器中目录。可固定写死。
其中 -v /postgre/data:/var/lib/postgresql/data 为数据库映射数据存储目录。
其中 -c 'config_file=/etc/postgresql/postgresql.conf' 强制数据库使用自定义的配置文件,忽略系统内置的配置信息 后面会介绍如何编写postgresql.conf文件。
九、替换容器中的pg_hba.conf配置文件
1、查询 容器id 执行
docker ps --filter "name=my-postgres-ssl" --format "{{.ID}}"
2、将配置文件复制容器中
docker cp /postgre/pg_hba.conf 容器ID:/var/lib/postgresql/data
3、重启docker容器
docker restart 容器ID
4、查看运行日志
docker logs -f --tail 200 容器ID
5、如图则运行成功
十、使用客户端连接数据库 此处使用Navicat
其中SSL配置中 客户端密钥 上传 server.key
客户端证书 上传 server.crt
根证书 上传 root.crt
点击【测试链接】