Postgres SSL连接错误:收到致命警报:handshake_failure

时间:2018-08-02 10:16:11

标签: postgresql ssl

Ubuntu Bionic上的Postgresql版本10

用于生成服务器证书的简单脚本

#!/bin/bash

if [ -z $1 ] || [ -z $2 ];
    then
        echo "Usage: ./self-signed-server-certificates <curve> <signing-user>"
    exit 1
fi

CURVE=$1
SIGNING_USER=$2

openssl ecparam -name $CURVE -out private.pem -genkey
openssl req -new -sha256 -key private.pem -out server.csr
openssl x509 -req -sha256 -days 365 -in server.csr -signkey private.pem -out certificate.crt
chmod 400 private.pem
sudo chown postgres:postgres private.pem cp certificate.crt root.crt

另一个用于生成客户端证书的简单脚本

#!/bin/bash

if [ -z $1 ] || [ -z $2 ] || [ -z $3 ] || [ -z $4 ];
    then
        echo "Usage: ./self-signed-server-certificates <curve> <signing-user> <root certificate path> <server key path>"
    exit 1
fi

CURVE=$1
SIGNING_USER=$2
ROOT_CERTIFICATE=$3
SERVER_KEY=$4

openssl ecparam -name $CURVE -out private.pem -genkey
openssl req -new -sha256 -key private.pem -out server.csr
openssl x509 -req -sha256 -in server.csr \
-CA $ROOT_CERTIFICATE -CAkey $SERVER_KEY -out public.crt -CAcreateserial
chmod 400 private.pem
sudo chown postgres:postgres private.pem

在我设置postgres的DigitalOcean上,这是我生成服务器证书的方式

// assume we are in newly created droplet and created another super user(not root) called thor

sudo apt-get -y -qq update >> /dev/null && sudo apt-get -y -qq install postgresql postgresql-contrib >> /dev/null

cd ~ && mkdir experiment && touch experiment/gen_server_cert.sh

// paste the above generate server certificate code to it, chmod +x for it then run with

./gen_server_cert.sh brainpoolP512t1 thor

// interactive shell will come up to ask about info and blab blah, just enter blank line for all except the password challenge field, assume I entered "123!@#QWEqwe"

它成功输出了4个文件,分别是:certificate.crt private.pem root.crtserver.crs,然后将它们复制到/etc/ssl/

sudo cp private.pem /etc/ssl/private/postgresql_private.pem && sudo cp root.crt /etc/ssl/certs/postgresql_server.crt

在实际设置SSL之前,我想验证是否可以使用dbeaver从本地计算机成功进行远程连接。

我首先为postgres创建一个角色,创建一个testdb,更改一些配置以允许来自外部的连接

sudo -u postgres -i
createuser -P -s -e thor // another interactive shell came up, enter password then done
// ctrl + d to get out from postgres
createdb ssl_test_db

sudo vim /etc/postgresql/10/main/pg_hba.conf

// inside pg_hba.conf add this line
...
host ssl_test_db thor 0.0.0.0/0 md5
...

sudo vim /etc/postgresql/10/main/postgresql.conf

// inside postgresql.conf uncomment the listen line and change it to listen to *

listen_addresses '*'

sudo service postgresql restart

// from dbeaver at my client machine, the setting for the connect are
Host: host_ip
Port: 5432
Database: ssl_test_db
User: thor
password: myverysecretpassword

// hit the button and yes it successfully connected

然后我再次更改那些配置以使用ssl

// inside pg_hba.conf comment the line that just added and add this one
hostssl ssl_test_db thor 0.0.0.0/0 md5 clientcert=1

// inside postgresql.conf uncomment some line and change some line
ssl = on
ssl_ciphers = 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK' # allowed SSL ciphers
ssl_prefer_server_ciphers = on
ssl_ecdh_curve = 'brainpoolP512t1'
ssl_cert_file = '/etc/ssl/certs/postgresql_server.crt'
ssl_key_file = '/etc/ssl/private/postgresql_private.pem'
ssl_ca_file = '/etc/ssl/certs/postgresql_server.crt'

// out to terminal
sudo service postgresql restart

// check for status
pg_lsclusters

// output
Ver Cluster Port Status Owner    Data directory              Log file
10  main    5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log

然后我从本地计算机打开另一个终端,sftp到它,并获取那些必要的文件以生成客户端证书

sftp> cd experiment
sftp> get root.crt
sftp> get private.pem

然后在我的本地计算机上,创建一个空文件夹,复制粘贴生成客户端证书脚本,chmod + x然后运行它以生成那些密钥和证书

// assume at ~
// the files that get from server will also be at ~
mkdir experiment && cd experiment && vim gen_client_cert.sh // copy paste in
chmod +x ./gen_client_cert.sh

./gen_client_cert.sh brainpoolP512t1 thor ../root.crt ../private.pem

它将成功生成3个文件,分别是:private.pem public.crtserver.scr

返回dbeaver,使上述基本连接设置保持不变,进入SSL选项,这些设置为:

Use SSL - enabled
Root certificate: ~/root.crt
SSL certificate: ~/experiment/public.crt
SSL certificate key: ~/experiment/private.pem

当我按下测试连接按钮时,会发生错误,并且消息是:

SSL error: Received fatal alert: handshake_failure

来自服务器的日志是:

LOG:  could not accept SSL connection: no shared cipher

生成的公共证书的验证:

// back to terminal at local machine and current directory at ~
openssl verify -CAfile root.crt -purpose sslclient experiment/public.rt

// output
experiment/public.crt: OK

0 个答案:

没有答案