Google App Engine - 开发服务器上 proxy/tunneling 的权限被拒绝

Google App Engine - permission denied for proxy/tunneling on development server

免责声明:这不是重复的!

我正在使用请求库,在 GAE 标准环境下修补猴子,一切都完美无缺,除了我在请求调用中添加额外的 proxy 参数的时候。这个代理意味着隧道和套接字操作,默认情况下开发和部署环境的标准配置禁用:

NotImplementedError: HTTP CONNECT Tunnelling is not supported https://pastebin.com/YDsG9we7

很好,所以我们需要在我们的 GAE 平台下启用真正的套接字支持,因此添加:

env_variables: GAE_USE_SOCKETS_HTTPLIB : "True"

即使不执行请求工具带猴子补丁(根本不使用 urlfetch),我们也会被拒绝许可:https://pastebin.com/ifBFKi3K

这通常发生在沙箱认为您正在访问禁止的服务器位置或端口时,但代理功能齐全并且猜猜是什么,我已经测试了完全相同的代码(由于开发或将服务器部署为当前环境,没有任何 added/removed 功能)并且它在部署时按预期工作,没有任何类型的 Permission denied 错误,通过使请求完全成功(如果我们尝试不启用 httplib 套接字,在两种情况下我们仍然会遇到 Tunnelling is not supported 错误,这是预期的行为)。

现在,我在部署上有了一个可行的解决方案(这才是真正重要的),但这对我来说还不够,我只想在我的开发服务器和环境下通过代理测试这些请求,所以我尝试做的是以下内容:

没关系...

有什么方法可以结束这场噩梦并继续使用标准环境吗?如果它在没有任何补丁的情况下在部署服务器上运行,为什么不也可以使用 dev_appserver 工具呢?

我只是不想做更多的补丁,我只是想克服远程部署服务器下不会抛出的 Permission denied 错误,使用完全相同的代码逻辑,无论是否我们使用请求、urlfetch、httplib、套接字等(只是代理所需的隧道)。

Digged-in 问题更进一步,似乎在这个文件中:

platform/google_appengine/google/appengine/api/remote_socket/_remote_socket_stub.py 在常量 _MOCK_SOCKET_OPTIONS 中找到一些模拟套接字对 (level, option) 缺少 (1, 3 ) 对,我的意思是下面的级别和选项的乘积之一(我猜星号是所需的值):

级别(值:1):

  • SOCKET_TCP_NODELAY
  • SOCKET_IP_TOS
  • SOCKET_SOL_SOCKET *
  • SOCKET_SO_DEBUG

选项(值:3):

  • SOCKET_IP_HDRINCL
  • SOCKET_SO_TYPE *
  • SOCKET_TCP_CORK

所以通过设置代理,我想我是在请求 SOL_SOCKET:SO_TYPE 组,但是模拟值呢?是一个十六进制二进制相关字符串,如“00000000”(用于保持活动)和“01000000”(重用地址):https://github.com/GoogleCloudPlatform/python-compat-runtime/blob/master/appengine-compat/exported_appengine_sdk/google/appengine/api/remote_socket/_remote_socket_stub.py#L97

在哪里可以找到 (1, 3) 个缺失对的此类值?


稍后编辑:

我已经添加了 "SOL_SOCKET:SO_TYPE=80000000" 组,现在它在 ssl 模块上中断(需要启用以支持 https;无需修补,只需在 app.yaml 中启用它): https://pastebin.com/9KQjdEgL 通过识别 128 的套接字类型,我猜这可能是以下常量之一:

  • socket.MSG_EOR
  • socket.SOMAXCONN
  • socket.TIPC_SRC_DROPPABLE

稍后...

所以我意识到 128 值实际上是我上面的 little-endian 模拟值,因此我将组更改为:"SOL_SOCKET:SO_TYPE=01000000" 并且它识别 socket.SOCK_STREAM 套接字类型,它实际上仅适用于此检查,但它再次崩溃,因为 ssl 不理解 GAE 的自定义套接字对象:https://pastebin.com/t2pUuW2V (<google.appengine.api.remote_socket._remote_socket.socket object at 0x7f0cd037f690>)。在有和没有 requests monkey-patching.

的情况下都试过了

我的结论

GAE 自定义 socket 不能完全与 SSL 一起工作(在隧道上)并且 Python 标准 socket 不能与 GAE 一起工作(non-patch-able 我猜)select 模块,关于 dev_appserver 沙箱。

解决方案:将远程部署的相同行为引入本地开发环境。