Perl - DBI and .pgpass
我可以使用以下命令成功创建到Postgres数据库的连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| my $settings = {
host => 'myhost',
db => 'mydb',
user => 'myuser',
passwd => 'mypasswd'
};
my $connection = DBI ->connect(
'DBI:Pg:dbname=' . $settings->{'db'} . ';host=' . $settings->{'host'},
$settings->{'user'},
$settings->{'passwd'},
{
RaiseError => 1,
ShowErrorStatement => 0,
AutoCommit => 0
}
) or die DBI ->errstr; |
但是我在Perl模块中留下了有价值的登录凭据(是的,我更改了它们)。当前,我使用psql进行交互式查询。为了省去记住用户名/密码的麻烦,我将凭据放在了权限为600的文件(?/ .pgpass)中。该文件如下所示:
1 2
| # host:port:database:user:passwd
myhost:5432:mydb:myuser:mypasswd |
如何安全使用此文件("$ENV{HOME}/.pgpass")和DBI模块隐藏我的凭据?能做到吗什么是最佳做法?
是的!有更好的方法。
在测试之间进行更改
-
甚至通过shell环境变量export PGSERVICE=test与my $dbh = DBI->connect("dbi:Pg:", undef, undef);连接
-
很酷的答案。我一直以来都希望有一种更好的方法来执行连接,而无需将很多连接信息硬编码到perl中。我已经使用相关字段创建了~/.pg_service.conf文件,但是我收到的是:ERROR: service file"/etc/sysconfig/pgsql/pg_service.conf" not found。有没有一种方法可以强制连接改为查看~/.pg_service.conf?
-
实际上,我自己找到了答案。我需要做的就是设置:$ENV{'PGSYSCONFDIR'}。谢谢!
按照上述问题,将登录凭据放入名为~/.pgpass的文件中。
要打开连接,您需要对主机,数据库和用户名进行硬编码。但这没关系,因为至少您不需要在密码字段中进行编码。此字段保持隐藏在您的~/.pgpass文件中。
确保将连接实例的密码字段设置为undef。
这是对我有用的东西:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| my $settings = {
host => 'myhost',
db => 'mydb',
user => 'myuser'
};
my $connection = DBI ->connect(
'DBI:Pg:dbname=' . $settings->{'db'} . ';host=' . $settings->{'host'},
$settings->{'user'},
undef,
{
RaiseError => 1,
ShowErrorStatement => 0,
AutoCommit => 0
}
) or die DBI ->errstr; |
连接成功建立,因为由于某种原因(至少我不知道),该实例在尝试连接时会搜索~/.pgpass文件。我知道此文件有些不可思议,只是不确定该如何处理。文件连结:
http://search.cpan.org/dist/DBI/DBI.pm#data_string_diff
请注意,在该页面上搜索" pgpass"如何不会返回?我拒绝阅读所有内容。好吧,也许有一天..
-
~/.pgpass是Postgres C客户端库libpq的功能。 DBI建立在libpq之上,因此它仅继承其功能。这就是为什么它可以与DBI一起使用的原因,以及为什么在DBI文档中未提及它的原因。
-
它是特定于PostgreSQL的,因此不应在DBI \\的文档中提及。另一方面,应该在DBD :: Pg \\中提到它,尽管不是。但是,后者确实提到了环境变量和不同的配置文件格式!
1 2 3 4 5 6 7 8 9 10
| open(my $fh, '<',"$ENV{HOME}/.pgpass") or die $!;
my $settings;
while (<>) {
chomp;
next if /^\\s*(?:#.*)?\\z/s;
@{$settings}{qw( host port database user passwd )} = split /:/;
}
die"No settings" if !$settings; |
任何能够运行脚本的用户仍然可以看到证书。
- 是的,但是肯定有更好的方法吗?我开始认为没有。
-
只需将凭据传递给$ connection实例,而无需声明它们或打开文件。
-
这是没有意义的。将args传递给函数与您提到的两件事无关。我再问一遍,确切的方法是做什么?后续问题显然将是更好的衡量标准?
-
对于错误的解释,我深表歉意。但是,我们的最后评论有助于找到解决方案。如果您对解决方案感兴趣,请参阅我的回答。再次感谢您的帮助。
-
抱歉,池上,我希望您不要介意,但我认为Craig在这里的答案最安全,分数也最少。再次感谢。
-
尽管此答案避免了对密码进行硬编码,但是如果您使用的是非libpq PostgreSQL连接,则如何将其作为命令行参数或环境变量发送是一个示例,并且与使用一样安全。来自libpq的pgpass文件,由于DBD :: Pg基于libpq,它重新发明了轮子。对于DBD :: Pg,让libpq处理它的.pgpass似乎是更好的做法