简体   繁体   English

如何解决Heroku上的“语言c权限被拒绝”错误?

[英]How to get around the “permission denied for language c” error on Heroku?

I have a project , which calls a Postgres function gen_random_bytes , which is declared like this: 我有一个项目 ,该项目调用Postgres函数gen_random_bytes ,其声明如下:

CREATE OR REPLACE FUNCTION core.gen_random_bytes(integer) RETURNS bytea AS '$libdir/pgcrypto', 'pg_random_bytes' LANGUAGE c STRICT;

It worked fine, as long as I used it on my local machine. 只要我在本地计算机上使用它,它就可以正常工作。 But I'm not able to create that function on Heroku - I get the following error: 但是我无法在Heroku上创建该函数-我收到以下错误:

[WARNING  ] CREATE OR REPLACE FUNCTION core.gen_random_bytes(integer) RETURNS bytea AS '$libdir/pgcrypto', 'pg_random_bytes' LANGUAGE c STRICT
ERROR:  permission denied for language c

It seems like only the superuser can declare functions in C. I found another answer , which recommends using the command 似乎只有超级用户才能在C中声明函数。我找到了另一个答案 ,建议使用命令

UPDATE pg_language SET lanpltrusted = true WHERE lanname LIKE 'c';

I don't have permission for that command, either: 我没有该命令的权限,或者:

ERROR: permission denied for relation pg_language
SQL state: 42501

How can I get my code work on Heroku? 我该如何在Heroku上使用我的代码?

I have at least following options: 我至少有以下选择:

  1. Rewrite core.gen_random_bytes in the Postgres language. 用Postgres语言重写core.gen_random_bytes
  2. Use some existing alternative for core.gen_random_bytes , which doesn't require superuser right. core.gen_random_bytes使用一些现有的替代core.gen_random_bytes ,它不需要超级用户权限。
  3. Switch from Heroku to another hosting provider, which would give me superuser rights (eg Digital Ocean, Amazon EC2 etc.) 从Heroku切换到另一个托管服务提供商,这将给我超级用户权限(例如Digital Ocean,Amazon EC2等)

Right now, I'm just prototyping this project. 现在,我只是对该项目进行原型设计。 Which option is the easiest one (including something that I didn't mention) ? 哪个选项最简单(包括我没有提到的选项)?

The answer is: you can't unless you run Postgres yourself on a bare instance (which I'm not sure is even an option on Heroku). 答案是:除非您自己在裸实例上运行Postgres(否则我不确定Heroku上的选项),否则您将无法进行。

The downside to all the Postgres hosted services (like Heroku and Amazon RDS) is that internally they need to be able to run multiple Postgres databases in a single virtual server. 所有Postgres托管服务(如Heroku和Amazon RDS)的不利之处在于,它们内部需要能够在单个虚拟服务器中运行多个Postgres数据库。 That means they can't allow Postgres to do anything that could possibly affect things at the OS level. 这意味着他们不能允许Postgres做任何可能影响操作系统级别的事情。 Untrusted procedure languages (such as C, plpythonu and plperlu, but NOT plperl) are able to do anything at the OS level that the OS user running Postgres can. 不受信任的过程语言(例如C,plpythonu和plperlu,但不是plperl)可以在运行Postgres的OS用户可以在OS级别执行任何操作。 That's a security hole that's unacceptable in a shared environment. 这是在共享环境中无法接受的安全漏洞。 (Just as an example, it'd be easy to go read raw Postgres data for every other customer on the server.) (仅举一个例子,很容易读取服务器上其他每个客户的原始Postgres数据。)

Your only option here is to install and manage Postgres yourself. 您唯一的选择是自己安装和管理Postgres。 On Amazon that's pretty easy; 在亚马逊上,这很容易。 just grab a raw EC2 instance with the OS of your choice and slap Postgres on it. 只需使用您选择的操作系统获取一个原始EC2实例,然后在其上拍一下Postgres。 You lose some of the ease of maintenance that RDS gives you, but if you know Postgres it's really not that big a deal. 您会失去RDS所提供的一些易于维护的功能,但是如果您知道Postgres,那确实没什么大不了的。 I tend to push my clients to do exactly that, so that I have the ability to use extensions that haven't been blessed by the RDS team (something else that's unsafe in a shared environment). 我倾向于敦促我的客户做到这一点,以便我能够使用RDS团队未曾赞过的扩展(在共享环境中这是不安全的)。

I'm not as familiar with Heroku's offerings, but as long as they have something comparable to a bare EC2 instance you can do the same thing. 我对Heroku的产品并不熟悉,但是只要它们具有与裸EC2实例相当的功能,您就可以做同样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM