【问题标题】:Protect user credentials when connecting R with databases using JDBC/ODBC drivers使用 JDBC/ODBC 驱动程序将 R 与数据库连接时保护用户凭据
【发布时间】:2014-12-03 16:39:52
【问题描述】:

通常我使用 JDBC/ODBC 驱动程序通过 R 连接到数据库。典型的代码如下所示

library(RJDBC)
vDriver = JDBC(driverClass="com.vertica.jdbc.Driver", classPath="/home/Drivers/vertica-jdbc-7.0.1-0.jar")
vertica = dbConnect(vDriver, "jdbc:vertica://servername:5433/db", "username", "password")

我希望其他人使用我的凭据访问数据库,但我想保护我的用户名和密码。所以我打算将上面的脚本保存为“Connections.r”文件,并要求用户获取这个文件。

source("/opt/mount1/Connections.r")

如果我只授予 Connections.r 执行权限,则其他人无法获取该文件

chmod 710 Connections.r

仅当我授予读取和执行权限时,R 才允许用户获取它。如果我授予读取权限,我的凭据将被公开。无论如何我们可以通过保护用户凭据来解决这个问题吗?

【问题讨论】:

  • 我不确定您是否可以超越混淆。如果您提供更多信息,为什么不为您的客户创建单独的用户,这可能会有所帮助。
  • 这一切是在一台共享机器上完成的,还是该代码部署在某个地方?基本的 shell 环境变量呢?
  • @bdecaf:数据很敏感,我只希望他们有读取权限。如果我创建单独的用户凭据,他们应该能够在本地计算机上下载数据。整个想法是保护数据库连接凭据,以便他们只能从部署此代码的一台服务器读取数据。
  • @Visser:这一切都在一台服务器上完成。我为用户设置了 R studio 服务器。我希望用户登录到该服务器并通过获取上述脚本来访问数据库,但我需要保护登录凭据。
  • 但是您可以将数据库设置为用户只能从指定的机器连接。

标签: linux r security unix rstudio


【解决方案1】:

凭据是否已发送as command arguments?这是一个如何做到这一点的示例:

suppressPackageStartupMessages(library("argparse"))
# create parser object
parser <- ArgumentParser()
# specify our desired options
# by default ArgumentParser will add an help option
parser$add_argument("-v", "--verbose", action="store_true", default=TRUE,
 help="Print extra output [default]")
parser$add_argument("-q", "--quietly", action="store_false",
 dest="verbose", help="Print little output")
parser$add_argument("-c", "--count", type="integer", default=5,
 help="Number of random normals to generate [default %(default)s]",
 metavar="number")
parser$add_argument("--generator", default="rnorm",
 help = "Function to generate random deviates [default \"%(default)s\"]")
parser$add_argument("--mean", default=0, type="double", help="Mean if generator == \"rnorm\" [default %(default)s]")
parser$add_argument("--sd", default=1, type="double",
 metavar="standard deviation",
 help="Standard deviation if generator == \"rnorm\" [default %(default)s]")
# get command line options, if help option encountered print help and exit,
# otherwise if options not found on command line then set defaults,
args <- parser$parse_args()
# print some progress messages to stderr if "quietly" wasn't requested
if ( args$verbose ) {
 write("writing some verbose output to standard error...\n", stderr())
}
# do some operations based on user input
if( args$generator == "rnorm") {
 cat(paste(rnorm(args$count, mean=args$mean, sd=args$sd), collapse="\n"))
} else {
 cat(paste(do.call(args$generator, list(args$count)), collapse="\n"))
}
cat("\n")

样品运行(无参数):

usage: example.R [-h] [-v] [-q] [-c number] [--generator GENERATOR] [--mean MEAN] [--sd standard deviation]
optional arguments:
 -h, --help show this help message and exit
 -v, --verbose Print extra output [default]
 -q, --quietly Print little output
 -c number, --count number
 Number of random normals to generate [default 5]
 --generator GENERATOR
 Function to generate random deviates [default "rnorm"]
 --mean MEAN Mean if generator == "rnorm" [default 0]
 --sd standard deviation
 Standard deviation if generator == "rnorm" [default 1]

这个包显然是受到同名的python 包的启发,所以looking there 也可能有用。

看看你的代码,我可能会重写如下:

library(RJDBC)
library(argparse)
args <- ArgumentParser()
args$add_argument('--driver', dest='driver', default="com.vertica.jdbc.Driver")
args$add_argument('--classPath', dest='classPath', default="/home/Drivers/vertica-jdbc-7.0.1-0.jar")
args$add_argument('--url', dest='url', default="jdbc:vertica://servername:5433/db")
args$add_argument('--user', dest='user', default='username')
args$add_argument('--password', dest='password', default='password')
parser <- args$parse_args
vDriver <- JDBC(driverClass=parser$driver, parser$classPath)
vertica <- dbConnect(vDriver, parser$url, parser$user , parser$password)
# continue here

【讨论】:

  • 我认为这对我没有帮助。目标是在不知道用户名和密码的情况下为所有最终用户使用单一凭据。即使我使用 'argparse' 选项,我也需要将此文件的读取权限授予最终用户。在这种情况下,他们仍然可以看到默认的用户名和密码。
  • 不,你没有。您只需要将密码指定为参数。如果您只需要给用户读取权限,您可以embed R 并编写一个存储过程来做您想做的事情。
  • 如果我必须指定密码作为参数,我仍然必须与最终用户共享密码。正确的?我想指出 R UDF 不在我的选择范围内。这是我使用 RJDBC 连接的主要原因。我也尝试运行你上面提到的代码,我得到这个错误“parser$classPath 中的错误:'closure' 类型的对象不是子集”
  • 嗯...我的下一个建议是使用shiny 将您的数据实时公开给最终用户。
【解决方案2】:

您想授予某人访问权限,但不让他们看到您的凭据吗?在这种情况下这是不可能的。如果我的代码可以读取文件,我可以看到文件中的所有内容。

在 SQL 服务器上创建更多帐户。或创建一个访客帐户。但是您正在尝试解决帐户管理解决的问题。

【讨论】:

    【解决方案3】:

    除非您要通过创建一个 Rcpp 函数或包来执行初始 JDBC 连接(这不会是微不足道的)来深度混淆您的凭据,否则您唯一较轻的混淆机制之一是将您的凭据存储在一个文件中,并让您的源 R 脚本从文件中读取它们,在调用中使用它们,并在调用之后立即从环境中使用它们 rm 它们。这仍然会暴露它们,但不会直接暴露。

    由于用户有自己的 RStudio Server 登录名,另一种方法是使用 Hadley 的新 secure 包(我们中的一些人正在按照它的步伐运行它),添加用户密钥并拥有您的凭据存储加密,但让您的源 R 脚本自动解密它们。您仍然需要对您使用的任何变量执行rm,因为如果您不这样做,它们将成为环境的一部分。

    最后一种方法,因为无论如何您都在授予他们访问数据的权限,所以是使用一组单独的凭据(您表达问题的方式似乎是您正在使用 your 凭据这)仅在这些分析所需的数据库和表的只读模式下工作。这样一来,如果信用泄漏也没关系,因为没有什么“坏”可以用它们来做的。

    最后,我很困惑为什么不能在数据库端设置具有只读权限的用户?这就是基于角色的访问控制的用途。这是行政工作,但绝对是正确的做法。

    【讨论】:

    • 我对数据库没有任何管理员权限。我只能使用我的凭据来读/写数据库。同时我需要让一群人使用一个专用的 RStudio 服务器,从数据库中读取数据并进行分析。如果我为用户设置了只读权限,他们可以使用本地机器读取数据并将其保存在本地。我需要保护它。
    • 你能设置其他基础设施吗?您可以使用 sqlrelay 之类的东西作为代理并以这种方式强制执行限制(不确定它是否有限制位,但其他人会这样做)。
    • 我明白你的意思,但在我的情况下,为这个问题设置另一个基础设施将被认为是低效的。
    • 我知道你的老板不想要更多的基础设施,但另一种选择是不安全的设置。句号。
    【解决方案4】:

    Jana,您愿意让用户通过 R 进行连接,但不以任何其他方式进行连接,这似乎很奇怪。这如何掩盖了他们的任何事情?

    我不明白为什么您会对拥有特定表(甚至视图)的特定 SELECT-only 访问权限的访客帐户不满意?

    【讨论】:

    • @MontesChemist:我的主要挑战是保护本地存储的数据(在专用服务器之外),同时我还需要一组人来分析它。即使我分配了一个访客帐户并与该组共享凭据。他们可以使用这些凭据通过 R/RJDBC 来“读取”数据,并将其“保存”在本地系统上。
    • 我了解您希望保护您的数据。我不明白的是如何保护它(通过 R 中一些尚未发现的机制)为您提供比 PostgreSQL 中的只读访问更多的保护。也就是说,为了分析 R 中的数据,人们不需要读取它(读入 R 中的一些向量)吗?如果是这样,这比 PostgreSQL 中的只读(选择)访问更安全吗?我真的很想在这里提供帮助,但我还没有看到区别......
    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    相关资源
    最近更新 更多