2

我有以下代码,我建立在我在网上找到的东西上(不记得在哪里)

$Server = XXXXX
$port = XXX
$remotepath='/'
$username = 'XXXX'
#$passward = ConvertTo-SecureString -AsPlainText 'XXXX' -Force 
$password = 'XXXXX'
$file = "path-to-file"

$f = Get-Item $File
$remote_url = "ftp://$Server`:$Port$RemotePath"

[System.Net.FtpWebRequest]$req = [System.Net.FtpWebRequest]::Create($remote_url + $f.Name)
# [System.Net.FtpWebRequest]$req = [System.Net.WebRequest]::Create($remote_url + $f.Name)
$req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)
$req.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$req.EnableSsl = $true
$req.UseBinary = $true
$req.UsePassive = $true
$req.KeepAlive = $true
$req.ConnectionGroupName = "FTPS_$Username"
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {return $true}
$fs = New-Object IO.FileStream $f.FullName, 'Open', 'Read'
$req.ContentLength = $f.Length
$ftpStream = $req.GetRequestStream()

$b = New-Object Byte[](10000)

do {
   $ftpStream.Write($b, 0, $r)
   $r = $fs.Read($b, 0, 10000)
} while ($r -ne 0)

if ($fs -ne $null) { $fs.Dispose() }
$ftpStream.Close()    
$resp = $req.GetResponse()
$resp.StatusDescription
$resp.Close()

该文件上传正常,但是当以下行被触发时:

$ftpStream.Close() 

它会在服务器(ubuntu 上的 vsftp)上导致以下错误:

Sun Mar 31 13:58:13 2019 [pid 3779] [XXXX] DEBUG: Client "XXX.XXX.XXX.XXX", "DATA connection terminated without SSL shutdown. Buggy client! Integrity of upload cannot be asserted."
Sun Mar 31 13:58:13 2019 [pid 3780] [XXXX] FTP response: Client "XXX.XXX.XXX.XXX", "426 Failure reading network stream."
Sun Mar 31 13:58:13 2019 [pid 3780] [XXXX] FAIL UPLOAD: Client "XXX.XXX.XXX.XXX", "/file-path", 36851 bytes, 0.21Kbyte/sec
Sun Mar 31 13:58:13 2019 [pid 3779] [XXXX] DEBUG: Client "XXX.XXX.XXX.XXX", "Control connection terminated without SSL shutdown."

这反过来导致我的代码中出现以下行:

$resp = $req.GetResponse()

失败:

Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: (426) Connection closed; transfer aborted."
At line:3 char:13
+             $resp = $req.GetResponse()
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : WebException

非常感谢所有帮助,因为如果上传失败或成功,脚本能够可靠地发出警报非常重要。

============= 更新 ==============

好吧,我没有发布此更新作为答案(至少现在还没有),因为它更多的是一种解决方法,而不是一个适当的解决方案。

我发现这篇中文帖子:https ://blog.yuwu.me/?p=1159我对此一无所知(这对我来说简直就是中文),但他做了 vsftpd 文档的配额部分:

strict_ssl_read_eof 如果启用,SSL 数据上传需要通过 SSL 终止,而不是套接字上的 EOF。需要此选项以确保攻击者不会使用伪造的 TCP FIN 过早终止上传。不幸的是,默认情况下没有启用它,因为很少有客户端能正确使用它。(v2.0.7 中的新功能)。

Default: NO

我将此设置添加到我的配置中,你瞧——我的脚本成功完成。但是,服务器继续抛出错误“数据连接在 SSL 关闭的情况下终止。错误的客户端!无法断言上传的完整性。” 但至少它不再终止我的控制通道。

显然,真正的解决方案是正确终止数据连接,因此希望有人能够成功解决此问题。

4

0 回答 0