暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

熊大开讲:PostgreSQL中的几种连接方式介绍

数据库杂记 2024-05-16
85

前言

最近,熊大安排工作时,让新来的小强,找时间总结一下PostgreSQL数据库当中各种各样的连接方式,并分析其中的特点。小强私下问小芳以及小玲子,同是新来的同事,为何不把这个事情安排给她们,难道不是女士优先吗?小玲子笑道:“吃亏是福啊,何况这也不是什么特别难做的事。” 于是小强就把这把这件事情应承下来。

连接无非是建立客户端到服务器端的联系,环境不同,连接方式肯定也不太相同,上边需要的是把各种各样的情况总结汇总一下,以便于拿来就可以使用。

分析

1、命令行客户端

这里指的就是psql命令行了。

情形1:不带参数的psql

[08:33:07-postgres@centos1:/var/lib/pgsql]$ psql
psql (14.10)
Type "help" for help.

postgres=# \c
You are now connected to database "postgres" as user "postgres".
postgres=# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5555".

这里不一定要任何参数时,通过命令\conninfo,可以看到,它连接的是本机,通过unixsocket: /var/run/postgresql,使用的是默认端口:5555 (由环境变量:PGPORT定义)

postgres=# \! echo $PGPORT
5555

实际上,它就相当于是下边的命令行:

psql -h /var/run/postgresql -p 5555 -U postgres -d postgres

-h后边可以是完整的主机名,使用的就是TCP socket,如果是Unix Socke目录,则使用Unix套接字,用于本机直连。

情形2:在psql中连接其它数据库

\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}

mydb=> \c mydb mydb 127.0.0.1 5555
Password for user mydb:
You are now connected to database "mydb" as user "mydb" on host "127.0.0.1" at port "5555".

依次填写数据库名、用户、主机、端口信息,即可完成连接。如果是默认值,使用 "-"略过。

mydb=> \c - postgres - -
Password for user postgres:
You are now connected to database "mydb" as user "postgres".
mydb=#
这表示 ,数据库不变,还是mydb, 然后主机我只用然还是127.0.0.1, 端口依然是5555
mydb=# \conninfo
You are connected to database "mydb" as user "postgres" on host "127.0.0.1" at port "5555".

也可以使用

另一种方式:(用host=, port=, user=的方式来指定)

[16:19:51-postgres@centos1:/var/lib/pgsql]$ psql "host=localhost port=5555 user=mydb"
Password for user mydb:
psql (14.10)
Type "help" for help.

mydb=>

而免于输入密码的方式,可以使用.pgpass文件里头指定密码。

还有一种连接串的方式:类似于JDBC URL的方式:postgresql://mydb@192.168.0.6:5555/mydb

[16:45:21-postgres@centos1:/var/lib/pgsql]$ psql postgresql://mydb@192.168.0.6:5555/mydb
Password for user mydb:
psql (14.10)
Type "help" for help.

mydb=>

情形3:双向认证连接方式

sslmode=verify-ca  (双向),  这个参数的值的指定是重点

psql -U testcert "host=192.168.0.10 dbname=mydb port=5555 user=testcert sslmode=verify-ca"

[08:26:48-postgres@ubuntu-linux:/var/lib/postgresql/.postgresql]$ psql "host=192.168.0.10 dbname=mydb port=5555 user=testcert sslmode=verify-ca"
psql (14.5 (Ubuntu 14.5-0ubuntu0.22.04.1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

mydb=>
// 这里头:-U testcert, 应该就是证书中的common name.

或者:
[postgres@ubuntu-linux:/var/lib/postgresql]$ psql postgresql://testcert@192.168.0.10:5555/mydb?sslmode=verify-ca
psql (14.5 (Ubuntu 14.5-0ubuntu0.22.04.1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres@ubuntu-linux:/var/lib/postgresql]$ psql postgresql://test:test123@192.168.0.10:5555/mydb?sslmode=verify-ca
psql: error: connection to server at "192.168.0.10", port 5555 failed: FATAL:  certificate authentication failed for user "test"
// 这个是说test用户是不能用cert进行认证的。

2、pgAdmin

简单的连接,都很直观,不用赘述。这里就介绍带证书的连接方式:(再具体的内容可以参考文本的第一篇文章: PostgreSQL中配置单双向SSL连接详解

填写注册server的信息:

image-20230903201243935

我们会发现,这里不需要填写密码信息。

然后看看SSL这一步:

image-20230903201321351

于是,很简单的就能连接到数据库。注意上边的root.crt是由server.crt复制而成。

image-20230903201437002

3、DBEaver

同样是介绍 带证书的连接方式:

如果我们照抄pgAdmin,可能会失败,如:

image-20230903203300664

将上边的路径改一下,改成postgresql.key.pk8,连接就成功了。

image-20230903204302725

image-20230903204324795

4、标准接口客户端

这里主要就是指Java的JDBC连接。有什么值得注意的地方吗?主要是双向证书的连接方式:

可以仿照DBEaver 里头的连接属性来搞。我们不妨试一下,代码也非常简洁:

package com.demo.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class PostgreSQLSSL2Demo {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://192.168.0.10:5555/mydb";
        Properties info = new Properties();
        info.put("user""testcert");
        info.put("sslcert""C:/tools/cert/ssl2/postgresql.crt");
        info.put("sslkey""C:/tools/cert/ssl2/postgresql.key.pk8");
        info.put("sslmode""verify-ca");
        info.put("sslrootcert""C:/tools/cert/ssl2/root.crt");
        try (Connection conn = DriverManager.getConnection(url, info)) {
            try (Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery("select version()")) {
                if (rset.next()) {
                    System.out.println("res: " + rset.getString(1));
                }
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
}

上边的代码也就是连接成功以后,简单的输出一下version()

resPostgreSQL 14.8 on x86_64-pc-linux-gnucompiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit

单向SSL可能的连接串的设置,大概如下:

tsslfactony=org.postgresg..ssl.NonValidatingFactory
jdbc.postgresal://hostname:port/databasename?ssl=true&sslfactony=org.postgresg.ssl.NonValidatingFactory
jdbc.postgresal://hostname:port/databasename?ssl=true&sslmode=requre

小结一下:

  • 要对pem/crt格式的客户端证书的私钥postgresql.key进行转换,转成pkcs8格式的postgresql.key.pk8,这样java程序中的"sslkey"参数能认定这种格式的文件

  • properties中指用户名,用的是属性"user",而不是"username",否则你指错了,它会取当前的操作系统 的user当username。

总体来说,把DBEaver中的相应参数拿过来用,还是挺方便的。

我是【Sean】,  欢迎大家长按关注并加星公众号:数据库杂记。为你提供及时更新。发送消息1或2或3或4, 分别都有好资源相送。

往期导读和参考:
1. PostgreSQL中配置单双向SSL连接详解
2. 提升PSQL使用技巧:PostgreSQL中PSQL使用技巧汇集(1)
3. 提升PSQL使用技巧:PostgreSQL中PSQL使用技巧汇集(2)
4. PostgreSQL SQL的基础使用及技巧
5. PostgreSQL开发技术基础:过程与函数

文章转载自数据库杂记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论