我有一个PHP代码与工作罚款。
$host = 'ftp.someserver.com';
$port = 21;
$pass = 'xxxx';
$user = 'username';
$connect = ftp_ssl_connect($host, $port);
$login = ftp_login($connect, $user, $pass);
if ($login) {
ftp_pasv($connect, true);
$list = ftp_mlsd($connect, ".");
var_dump($list);
}
else {
exit(error_get_last());
}
ftp_close($connect);
从WinSCP连接(c#示例):
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "ftp.someserver.com",
UserName = "username",
Password = "xxxx",
FtpSecure = FtpSecure.Explicit,
TlsHostCertificateFingerprint = "dd:70:5c:67:xx:xx:xx:....",
TimeoutInMilliseconds = 45000,
};
sessionOptions.AddRawSettings("FtpForcePasvIp2", "1");
我需要在nodejs上写这个,试图使用basic-ftp包,但总是给予错误:
SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:
] {
library: 'SSL routines',
function: 'ssl3_get_record',
reason: 'wrong version number',
code: 'ERR_SSL_WRONG_VERSION_NUMBER'
}
UPD:
这是我在node.js上的示例代码,在我的本地windows机器上,我得到了如上所述的错误,在其他机器上,就像这样。不太明白是什么原因,需要插入到secureOptions
,但认为它需要。
const ftp = require("basic-ftp")
const config = {
host: "ftp.someserver.com",
user: "username",
password: "xxxx",
port: 21,
secure: true,
}
const client = new ftp.Client()
// client.ftp.verbose = true
try {
await client.access(config)
console.log(await client.list())
}
catch(err) {
console.log(err)
}
client.close()
控制台输出(在我看来隐藏了一些不重要的细节):
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Host: ftp.shopdrawing.co.il. is not in the cert's altnames: DNS:cp31.box.co.il
at new NodeError (node:internal/errors:387:5)
at Object.checkServerIdentity (node:tls:354:12)
at TLSSocket.onConnectSecure (node:_tls_wrap:1545:27)
at TLSSocket.emit (node:events:513:28)
at TLSSocket._finishInit (node:_tls_wrap:949:8)
at TLSWrap.ssl.onhandshakedone (node:_tls_wrap:730:12) {
reason: "Host: ftp.shopdrawing.co.il. is not in the cert's altnames: DNS:cp31.ox.co.il",
host: 'ftp.shopdrawing.co.il',
cert: {
subject: ...,
issuer: [Object: null prototype] { ... },
subjectaltname: 'DNS:cp31.box.co.il',
infoAccess: [Object: null prototype] { ... },
modulus: '....',
bits: 2048,
exponent: '0x10001',
pubkey: <Buffer 30 82 01 ... >,
valid_from: 'Mar 24 00:00:00 2023 GMT',
valid_to: 'Jun 22 23:59:59 2023 GMT',
fingerprint: '8A:99:3A:xx:xx:......',
fingerprint256: 'DD:70:5C:xx:xx:......',
fingerprint512: '4F:84:8A:xx:xx:......',
serialNumber: '....',
raw: <Buffer 30 82 05 d2 ... >,
issuerCertificate: { ... },
code: 'ERR_TLS_CERT_ALTNAME_INVALID'
}
}
1条答案
按热度按时间eivnm1vs1#
reason:“主持人:ftp.shopdrawing.co.il.不在证书的别名中:DNS:cp31.ox.co.il“,
您正在尝试连接到名称为“www.example.com”的主机ftp.shopdrawing.co.il。该主机的FTP服务器的证书是“cp31.ox.co.il”,但与您连接的名称不匹配。这就是为什么你得到这个错误。
已通过
secureOptions: {checkServerIdentity: () => {return null;}}
解决,但不确定禁用服务器名称检查是否完全正确即使禁用证书验证的一部分也不是一个好主意。在这种情况下,您禁用了主机名验证,这意味着攻击者可以使用由受信任的CA颁发的任意有效证书来发起中间人攻击。
不幸的是,FTP服务器的设置似乎是一团糟。证书中的名称(“cp31.box.co.il“)无法解析为IP地址,因此您无法将其用作目标。最好的方法是正确地使用定义一个
checkServerIdentity
,就像你建议的那样,但不是接受任何东西,而是只接受具有特定指纹或特定主题的证书-请参阅此处以获取您可以从证书对象访问的属性。例如,您可以检查subjectaltname:
或通过指纹检查特定证书: