Unix Domain Socket与PostgreSQL的local连接

前言

前面章节中提到了PostgreSQL的peer认证方式,说到这种认证方式是通过Unix Domain Socket连接方式认证的。本章节就来详细谈谈Unix Domain Socket及其应用。

Unix Domain Socket VS TCP/UDP Socket

看到Socket这个词,很多人可能会联想到网络编程非常常见的TCP/UDP Socket。本质上他们的作用都一样,都是为了网络通信而生。Unix Domain Socket是在此基础之上发展的IPC机制,在本机两个进程之间直接建立通信方式,不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,所以性能上和效率上比TCP/UDP Socket高得多,并且Unix Domain Socket是一种可靠的通信机制,而network socket是不可靠的通信,可能发生丢包、乱序等现象。

Unix Domain Socket的表现形式

是以文件形式存放在本机上,通常不占用容量。以大多数运维人员非常熟悉的MySQL服务为例,默认配置下MySQL服务运行时会创建一个这样的文件:

# ll /var/lib/mysql/mysql.sock 
srwxrwxrwx 1 mysql mysql 0 12月 28 21:30 /var/lib/mysql/mysql.sock 
#^ 注意第一个file类型标记是s

# file  /var/lib/mysql/mysql.sock 
 /var/lib/mysql/mysql.sock : socket

不同的操作系统可能这个文件位置略有不同,具体位置参考MySQL的配置文件中的socket配置项。

咋一看有点像命名管道(named pipe),而且作用也差不多。但是命名管道只能支持字节流,而Unix Domain Socket既能支持字节流,又能支持队列。

另外Unix Domain Socket使用系统文件的地址来作为自己的身份,所以可以用于权限认证(PostgreSQL的Peer认证),它可以被系统进程引用。所以可以支持不同的进程同时使用,而命名管道是没有这种功能的。

Unix Domain Socket的使用

很多运行于Linux/Unix上的服务不止可以监听一个TCP/UDP端口,还支持监听一个Unix Domain Socket。如Mysql的socket配置,redis的unixsocket配置,nginx的listen配置,Postgresql的unix_socket_directories配置等等。只要客户端支持Unix Domain Socket,就可以直接使用这种方式连接。

如MySQL的[client]配置段下面socket配置就直接指向unix domain socket地址,代表默认使用unix domain socket连接。psql默认连接方式也是使用unix domain socket,会在/var/run/postgresql/目录下查找.s.PGSQL.5432这个socket。可以通过psql -h /path/to/socket/directory/ -p port切换其他目录下的socket文件。

大多数使用C/C++语言开发的client也都支持Unix Domain Socket。比如Python(使用官方的解释器Cython)的Mysql driver Connector/Python,就有这样的连接方式:

cnx = mysql.connector.connect(user='root',password='password',unix_socket='/var/lib/mysql/mysql.sock')

直接指定连接本地的Unix Domain Socket访问Mysql服务。

再比如PostgreSQL的Python driver Psycopg2的文档就直接写明connect()函数不指明host参数,默认就使用Unix Domain Socket等等。

再比如说流行的web服务器Nginx,可能很多人都没不知道Nginx的listen指令是可以支持unix domain socket的:

server {
  listen unix:/var/run/nginx.sock;
}

这样可以限制这个虚拟主机不能直接暴露给外网用户,需要暴露的时候可以在加一个反向代理,以便做一些其他的配置限制:

upstream backend-nginx {
  server unix:/var/run/nginx.sock;
}

server {
  location / {
    proxy_pass http://backend-nginx;
  }
}

Unix Domain Socket的限制

Unix Domain Socket的性能很高,安全性好,在network socket端口有限的情况下,Unix Domain Socket无需占用有限的TCP/UDP端口。现在谈谈这玩意的限制了。很明显的可以看到两个限制:

  • 只能本机访问,不能用于远程访问(Docker可以利用挂载的形式实现本机不同容器或容器与宿主机之前的访问,但还是在同一台主机上)
  • 只在POSIX兼容的系统有实现。意味着Windows下没有对应的实现,所以MySQL这一类的服务跑在Windows下就默认关闭Unix Domain Socket的功能了

还有就是像Java这种编程语言为了简化跨平台的兼容性问题,底层也不提供Unix Domain Socket的支持。比如JDBC就没有Unix Domain Socket的连接实现,所以jdbc url在连接本机服务的时候,也只能写127.0.0.1,不能写Unix Domain Socket路径。

PostgreSQL的local连接与peer认证

说清楚了Unix Domain Socket之后,PostgreSQL的peer认证就很容易理解了。

有关postgresql完整的认证方式,参见官方文档: https://www.postgresql.org/docs/current/auth-methods.html

我们先看看默认安装下的postgresql的pg_hba.conf文件(已过滤空行和注释行):

local   all             postgres                                peer
local   all             all                                     peer
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5

其中host代表client的访问方式是TCP,而local就代表client的访问方式是Unix Domain Socket。所以可以很明显的看到local行的配置是没有ip配置段的。

那么再说说peer认证方式是怎么回事呢?之前提到过,Unix Domain Socket是可以拿到用户身份信息的,这个在Unix/Linux系统中就是用户账号,而peer则代表着用户psql以user身份运行,连接到数据库上对应的用户身份就是user这种方式。所以peer认证只支持local连接方式,所以在windows不起作用。

举个例子,如果我当前以myuser这个账号登录到Linux系统中,运行psql命令,那么连接到数据库上就是myuser这个用户,不需要密码认证。如果postgresql数据库中没有myuser这个用户,就会报错找不到这个用户。

再看看postgres这个用户默认配置下限定local连接方式,认证方式是peer。代表postgres(默认的postgresql的管理员账户)必须以Unix Domain Socket方式连接,并且使用操作系统中的postgres用户身份运行。由于这个账户默认在Linux系统中是不允许直接登录的,所以我们需要susudo命令切换用户身份运行,这里我们以sudo为例:

sudo -u postgres psql

由于psql默认就是以Unix Domain Socket方式连接(Windows系统则以TCP方式),所以无需指定其他连接参数。

再比如我们在postgresql上创建了一个用户myadmin,但是我们的操作系统中没有myadmin这个账户,那么此时我们就不能使用local渠道连接了,只能以host方式连接,即TCP方式:

psql -U myadmin -h 127.0.0.1

直接指定-h参数为127.0.0.1localhost,限定psql使用TCP方式连接postgresql,则可以命中后面的host all all 127.0.0.1/32 md5这个配置,于是连接到数据库中。

psql使用unix domain socket连接本机其他postgresql实例的方案:

psql -h /path/to/socket/dir/ -p other_port
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • 在上一章中我们讲了怎么安装PostgreSQL,在数据库安装完成及启动数据库服务以后,需要连接到数据库上对数据库里...
    shark_tear阅读 84,653评论 3 2
  • 安装 详情参考官方安装文档 安装指定版本: 配置 postgresql的配置在/etc/postgresql/VE...
    冯宇Ops阅读 2,193评论 0 0
  • pg_ctl 名称 pg_ctl -- 启动、停止、重启 PostgreSQL语法 pg_ctl start [-...
    老肖阅读 896评论 0 0
  • 1.今天学习的主要内容 ? 贯穿。贯穿就是声音对于文字的整合能力,真正的贯穿是通过声音清晰地体现出句子的结构来完成...
    温大P39李佳琪阅读 130评论 1 1
  • 怕喜欢上我吗 可笑的理由 我这臭小子 从来没敢奢求过被爱 芸芸众生 今夜我难眠 大起大落的心境 犹如今日做过山车 ...
    露出了真身可会被抱紧阅读 280评论 0 0