【问题标题】:Proxy outbound API calls from Google App Engine via Google Compute Engine running Squid通过运行 Squid 的 Google Compute Engine 代理来自 Google App Engine 的出站 API 调用
【发布时间】:2020-05-12 22:46:51
【问题描述】:

我正在尝试通过运行 Squid 代理服务器的 Google Compute Engine 服务器 VM 实例代理从 Google App Engine 应用程序发出的出站 API 调用。

目标是所有 REST api 调用都来自静态 IP 地址,以便第 3 方 API 能够识别并允许通过其防火墙的调用。

我已阅读并遵循此帖子中的说明:

connect Google App Engine and Google Compute Engine

到目前为止,我已经做到了以下几点:

  1. 创建了一个 Google 云计算 VM 并成功为其分配了一个静态外部 IP 地址。
  2. 已成功创建无服务器 VPC 访问连接器(所有资源位于同一 GAE 区域)。
  3. 在我的 Google App Engine 项目(在 Node.js 上运行)中的 app.yaml 中添加了 vpc_access_connector 名称。
  4. 使用 gcloud beta 部署应用,API 调用针对代理服务器的内部 IP 地址,使用正确的 Squid 默认端口 (3128)。
  5. 从 GAE 应用程序发出请求时,我可以从服务器日志中看到正在尝试正确的 IP 地址和端口,但收到以下错误:“错误:无法建立隧道套接字,原因 = 连接 ECONNREFUSED [我的内部 IP 地址]:3128"

我也尝试过从云 shell 界面运行 curl 命令,但每次请求都会超时。

如果有人能帮助解决这个问题,我将非常感激。

【问题讨论】:

  • 什么是 App Engine 环境?标准还是灵活?我建议您关注documentation 的相关部分,它使用gcloud app deploy 而不是gcloud beta app deploy
  • @DanielOcando 抱歉,但我已经阅读了很多次,并且完全按照说明进行操作。在使用 gcloud beta 部署之前,我使用 gcloud 进行了部署,但没有任何区别。我现在创建了一个新的 vpc 连接器,使用 gcloud(非测试版)重新部署并创建了一个新的计算引擎 VM,看看我是否可以使用新的 vpc 连接器得到响应。我检查了 vpc 防火墙规则并确保端口对入口流量开放。如果我从 App Engine 卷曲到计算引擎 vm(+ 端口)的内部 IP 地址,它就会超时。
  • @DanielOcando - 另外,我使用的是标准环境。
  • 我可以看到“ECONNREFUSED”的两个可能原因:1。 SQUID server inside the Compute Engine Proxy 配置错误。通过 SSH 连接到 VM 并运行 sudo sed -i 's:#\(acl localnet src [SERVERLESS_VPC_ACCESS_CONNECTOR_IP]/28.*\):\1:' /etc/squid/squid.conf 以将您的无服务 VPC 访问连接器添加到 Squid's server ACL 然后 restart the server 以使更改生效。
  • 2. VPC 网络配置错误。您是否添加了防火墙规则以允许端口 3128 上的流量?如果您使用的是default network,则以下command 应该可以工作:gcloud compute firewall-rules create NAME --network default --allow tcp:3128(将 NAME 更改为您想要的防火墙规则名称)。

标签: google-app-engine google-compute-engine vpc


【解决方案1】:

这是一个可能的示例,说明如何通过运行 Squid 的 Compute Engine VM 在 NodeJS 运行时代理来自 App Engine 标准应用程序的出站 HTTP 请求,基于对可用的 Google Cloud Platform 文档12 的轻微修改和快速入门3

1.创建无服务器 VPC 访问连接器:基本上按照2 创建连接器。更新 gcloud 组件并在您的项目上启用无服务器 VPC 访问 API 后,运行以下命令就足够了:

gcloud compute networks vpc-access connectors create [CONNECTOR_NAME] \
--network [VPC_NETWORK] \
--region [REGION] \
--range [IP_RANGE]

2。创建 Compute Engine VM 用作代理:基本上按照1 设置 Squid 代理服务器:

一个。 Reserve a static external IP addressassign it to a Compute Engine VM

b.添加Firewall rule 以允许 Squid 的默认端口:3128 上的流量。如果您使用的是default VPC network,则此命令应该可以工作:gcloud compute firewall-rules create [FIREWALL_RULE_NAME] --network default --allow tcp:3128

c。使用以下命令在 VM 上安装 Squid sudo apt-get install squid3

d。在 Squid 配置文件中为 VPC Access 连接器启用 acl localnet src 条目:

sudo sed -i 's:#\(http_access allow localnet\):\1:' /etc/squid/squid.conf
sudo sed -i 's:#\(acl localnet src [IP_RANGE]/28.*\):\1:' /etc/squid/squid.conf

例如:如果您使用 10.8.0.0 作为 [IP_RANGE] 字段的值来创建连接器,它应该类似于 sudo sed -i 's:#\(acl localnet src 10.8.0.0/28.*\):\1:' /etc/squid/squid.conf

e。用sudo service squid start启动服务器

3. App Engine应用修改:在Quickstart for Node.js的基础上修改以下文件,以创建应用crawls a webpage using the request-promise library并显示网页的HTML。请求被发送到网页using the VPC Access connector 和虚拟机作为代理,修改了 app.yaml 和 app.js 文件。

一个。包.json

...
    "test": "mocha --exit test/*.test.js"
  },
  "dependencies": {
    "express": "^4.16.3",
    "request": "^2.88.0",
    "request-promise": "^4.2.5"
  },
  "devDependencies": {
    "mocha": "^7.0.0",
...

b. app.js

'use strict';
// [START gae_node_request_example]
const express = require('express');
const app = express();
app.get('/', (req, res) => {
  res
    .status(200)
    .send('Hello, world!')
    .end();
});
//Add a handler to test the web crawler
app.get('/test', (req, res) => {
  var request = require('request-promise');
  request('http://www.input-your-awesome-website.com')
    .then(function (htmlString) {
      res.send(htmlString)
         .end();
    })
    .catch(function (err) {
      res.send("Crawling Failed...")
         .end();
    });
});
// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});
// [END gae_node_request_example]

c。 app.yaml

runtime: nodejs10
vpc_access_connector:
  name: "projects/[PROJECT]/locations/[REGION]/connectors/[CONNECTOR_NAME]"
env_variables:
  HTTP_PROXY: "http://[Compute-Engine-IP-Address]:3128"
  HTTPS_PROXY: "http://[Compute-Engine-IP-Address]:3128"

每次您转到 /test 处理程序时,通过使用来自 VM 的 sudo tail -f /var/log/squid/access.log 命令并检查日志上的更改来监控请求是否通过代理。

注意事项:连接器、应用程序和 VM 需要位于同一区域才能工作,并且 these are the supported regions for the connector

【讨论】:

  • 进行出站请求时可以找到日志,但在日志中出现 TCP_DENIED 错误。如何调试出错的地方?
  • 你在哪里使用 app.yaml 中定义的 http_proxy 和 https_proxy 环境变量?应该使用哪个计算引擎 IP 地址?内部IP还是外部IP?
  • 代理的 env 变量旨在以与what's explained here 类似的方式在操作系统系统级别使用。您应该使用内部 IP,因为路由应该是 App Engine - VPC 连接器 - 内部 IP - Squid - 外部 IP。
  • 但更重要的是,这些解释已经非常过时了。因为这不是一个非常可扩展的解决方案。如果您想为 App Engine 分配静态 IP 地址,请使用 NEG,因为它是此用例的正确解决方案。所有信息都可以在here找到。
猜你喜欢
  • 1970-01-01
  • 2018-02-14
  • 2018-04-28
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 2017-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多