0

我的工作站位于公司代理后面,我已经设置了环境变量,并且可以使用除 aws-sdk 和 NodeJS 之外的所有内容。这里是 TCP 连接的转储:

No.     Time           Source                Destination           Protocol Length Info
  2 1.834143       105.103.15.106        105.103.82.47         TCP      74     54952 → 8080 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=497254718 TSecr=0 WS=128
  3 1.836141       105.103.82.47         105.103.15.106        TCP      74     8080 → 54952 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=3399116010 TSecr=497254718 WS=128
  4 1.836165       105.103.15.106        105.103.82.47         TCP      66     54952 → 8080 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=497254719 TSecr=3399116010
  5 1.836779       105.103.15.106        105.103.82.47         TCP      310    54952 → 8080 [PSH, ACK] Seq=1 Ack=1 Win=29312 Len=244 TSval=497254719 TSecr=3399116010
  6 1.838250       105.103.82.47         105.103.15.106        TCP      66     8080 → 54952 [ACK] Seq=1 Ack=245 Win=15616 Len=0 TSval=3399116012 TSecr=497254719
 20 123.670911     105.103.82.47         105.103.15.106        TCP      66     8080 → 54952 [FIN, ACK] Seq=1 Ack=245 Win=15616 Len=0 TSval=3399237839 TSecr=497254719
 21 123.674168     105.103.15.106        105.103.82.47         TCP      66     54952 → 8080 [FIN, ACK] Seq=245 Ack=2 Win=29312 Len=0 TSval=497285178 TSecr=3399237839
 22 123.676592     105.103.82.47         105.103.15.106        TCP      66     8080 → 54952 [ACK] Seq=2 Ack=246 Win=15616 Len=0 TSval=3399237843 TSecr=497285178

请注意,三次握手正常,然后客户端(以 106 结尾的 ip)在 5 号包上发送一些数据(psh,ack),然后立即接收代理的 ACK(6 号包)。然后很长一段时间没有通信(7和19之间的包不是来自这个tcp会话),包20是一个FIN(代理超时,因为没有发送包?)。此对话由 Amazon 提供的示例生成。

节点版本:在今天安装的 6.10.0、6.11.0 和 8.1.3 SDK 上测试 (2.82.0)

作为比较,我aws cloudformatin describe-stack-resources --stack-name my-stack在同一台 Ubuntu 机器上运行。众所周知,awsCLI 是 python,命令运行正常,对话如下:

No.     Time           Source                Destination           Protocol Length Info
  1 0.000000       105.103.15.106        105.103.82.47         TCP      74     54940 → 8080 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=496906305 TSecr=0 WS=128
  2 0.001987       105.103.82.47         105.103.15.106        TCP      74     8080 → 54940 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM=1 TSval=3397722434 TSecr=496906305 WS=128
  3 0.002008       105.103.15.106        105.103.82.47         TCP      66     54940 → 8080 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=496906305 TSecr=3397722434
  4 0.002100       105.103.15.106        105.103.82.47         TCP      127    [TCP segment of a reassembled PDU]
  5 0.003967       105.103.82.47         105.103.15.106        TCP      66     8080 → 54940 [ACK] Seq=1 Ack=62 Win=14592 Len=0 TSval=3397722436 TSecr=496906306
  6 0.003974       105.103.15.106        105.103.82.47         HTTP     68     CONNECT cloudformation.us-east-1.amazonaws.com:443 HTTP/1.0 
  7 0.006035       105.103.82.47         105.103.15.106        TCP      66     8080 → 54940 [ACK] Seq=1 Ack=64 Win=14592 Len=0 TSval=3397722438 TSecr=496906306
  8 0.247802       105.103.82.47         105.103.15.106        HTTP     185    HTTP/1.0 200 Connection established 
  9 0.247810       105.103.15.106        105.103.82.47         TCP      66     54940 → 8080 [ACK] Seq=64 Ack=120 Win=29312 Len=0 TSval=496906367 TSecr=3397722681
 10 0.248938       105.103.15.106        105.103.82.47         TLSv1.2  583    Client Hello
 11 0.250985       105.103.82.47         105.103.15.106        TCP      66     8080 → 54940 [ACK] Seq=120 Ack=581 Win=15616 Len=0 TSval=3397722683 TSecr=496906367
 12 0.684003       105.103.82.47         105.103.15.106        TLSv1.2  1995   Server Hello
 13 0.684011       105.103.15.106        105.103.82.47         TCP      66     54940 → 8080 [ACK] Seq=581 Ack=2049 Win=33152 Len=0 TSval=496906476 TSecr=3397723117
 14 0.690001       105.103.82.47         105.103.15.106        TLSv1.2  1488   CertificateServer Key Exchange, Server Hello Done
 15 0.690866       105.103.15.106        105.103.82.47         TLSv1.2  216    Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
 16 0.692974       105.103.82.47         105.103.15.106        TCP      66     8080 → 54940 [ACK] Seq=3471 Ack=731 Win=16640 Len=0 TSval=3397723125 TSecr=496906478
 17 0.968807       105.103.82.47         105.103.15.106        TLSv1.2  141    Change Cipher Spec, Encrypted Handshake Message
 18 0.969476       105.103.15.106        105.103.82.47         TLSv1.2  679    Application Data
 19 0.970992       105.103.82.47         105.103.15.106        TCP      66     8080 → 54940 [ACK] Seq=3546 Ack=1344 Win=17920 Len=0 TSval=3397723403 TSecr=496906547
 20 1.319977       105.103.82.47         105.103.15.106        TLSv1.2  617    Application Data
 21 1.324998       105.103.82.47         105.103.15.106        TCP      2114   [TCP segment of a reassembled PDU]
 22 1.325003       105.103.15.106        105.103.82.47         TCP      66     54940 → 8080 [ACK] Seq=1344 Ack=6145 Win=43008 Len=0 TSval=496906636 TSecr=3397723753
 23 1.329979       105.103.82.47         105.103.15.106        TLSv1.2  133    Application Data
 24 1.332987       105.103.15.106        105.103.82.47         TCP      66     54940 → 8080 [FIN, ACK] Seq=1344 Ack=6212 Win=43008 Len=0 TSval=496906638 TSecr=3397723763
 25 1.373825       105.103.82.47         105.103.15.106        TCP      66     8080 → 54940 [ACK] Seq=6212 Ack=1345 Win=17920 Len=0 TSval=3397723807 TSecr=496906638
 26 1.606041       105.103.82.47         105.103.15.106        TLSv1.2  119    Encrypted Alert
 27 1.606063       105.103.15.106        105.103.82.47         TCP      54     54940 → 8080 [RST] Seq=1345 Win=0 Len=0

注意从1到3的包是三次握手,和JS SDK完全一样,包4和JS SDK的包5类似,没有在总结中显示但它也有PSH标志和ACK,不同的是内容(预期) 并且数据包 5 是该数据的代理 ACK。从这一点开始,情况有所不同,awsCLI 在 ACK 到达数据包 6 后立即发送下一个数据包。收到数据后,awsCLI 发送 FIN,接收 ACK,加密警报并发送 RST(这是由于未预期的加密警报)。

我找不到为什么 JS SDK 在最后一个服务器 ACK 之后停止发送数据。但是由于代理超时并在某个时间后发送 FIN ACK,我的节点脚本似乎挂了很长时间,直到中止并出现以下错误:

{ NetworkingError: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1124:19)
at TLSSocket.g (events.js:292:16)
at emitNone (events.js:91:20)
at TLSSocket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)

消息:'socket hang up',代码:'NetworkingError',区域:'us-west-2',主机名:'bucket.s3-us-west-2.amazonaws.com',可重试:true,时间:2017- 07-07T19:31:29.494Z} 空

有什么线索吗?

4

2 回答 2

4

查看输出,CLI 连接正在使用 CONNECT(HTTP 隧道),如此处所述,而您的 NodeJS SDK 调用似乎没有这样做。似乎带有 CONNECT 类型代理的 NodeJS SDK 有点奇怪。我建议查看上面提到的使用node-tunnel给出这样的错误:

var AWS = require('aws-sdk');
var tunnel = require('tunnel');

var tunnelingAgent = tunnel.httpsOverHttp({
  proxy: { // Proxy settings
    host: 'proxyhost',
    port: 8080,
    proxyAuth: "user:pass",
  }
});

AWS.config.update({
  httpOptions: { 
    agent: tunnelingAgent
  }
});

var s3 = new AWS.S3({region: 'us-west-2'});
s3.getObject({Bucket: 'bucket', Key: 'key'}, function (err, data) {
  console.log(err, data);
});

虽然不幸的是我没有环境设置来测试这个,但我希望它至少能让你开始了解如何解决这个问题。

于 2017-07-07T22:51:28.233 回答
0

从 AWS SDK v3 开始,不再有用于配置代理的全局配置。必须将配置传递给实例化的每个服务客户端。

S3Client, 包的示例@aws-sdk/client-s3

使用aws-sdk-v3-proxy使用 HTTP_PROXY / HTTPS_PROXY 环境变量

import { S3Client } from '@aws-sdk/client-s3';
import { addProxyToClient } from 'aws-sdk-v3-proxy';

const client = addProxyToClient(new S3Client({}));

或配置自定义requestHandler

import { S3Client } from '@aws-sdk/client-s3';
import { NodeHttpHandler } from "@aws-sdk/node-http-handler";
import ProxyAgent from "proxy-agent";

// omit proxy url argument to use env variables HTTP_PROXY / HTTPS_PROXY
const proxyAgent = new ProxyAgent("http://internal.proxy.com");
new S3Client({
    requestHandler: new NodeHttpHandler({
        httpAgent: proxyAgent,
        httpsAgent: proxyAgent
    })
});

特殊情况:临时凭证

如果您使用 AssumeRole 为身份和访问管理 (IAM) 使用临时的、有限权限的凭证,则必须发出请求以获取它们。S3Client为此提供了选项credentials

但是,由于不再有全局配置对象,用于获取临时凭据的幕后STSClient客户端也必须配置为在代理后工作fromIni,fromTokenFile和其他提供的功能@aws-sdk/credential-providers有一个clientConfig 选项

import { S3Client } from '@aws-sdk/client-s3';
import { NodeHttpHandler } from "@aws-sdk/node-http-handler";
import ProxyAgent from "proxy-agent";
import { fromIni } from "@aws-sdk/credential-providers";

// omit proxy url argument to use env variables HTTP_PROXY / HTTPS_PROXY
const proxyAgent = new ProxyAgent("http://internal.proxy.com");

const requestHandler = new NodeHttpHandler({
    httpAgent: proxyAgent,
    httpsAgent: proxyAgent
})
new S3Client({
    credentials: fromIni({
        profile: "YourRoleProfile",
        clientConfig: {
            requestHandler
        }
    }),
    region: "eu-central-1",
    requestHandler
});
于 2021-11-12T00:53:34.643 回答