Я использую pure-ftpd 1.0.46 на Ubuntu 18.04 в качестве сервера, с TLS и сертификатами, подписанными Let's Encrypt. У меня нет проблем с подключением и передачей по глобальной сети. Я использую пассивный режим, порты переадресованы правильно, и я настроил pure-ftpd для ответа по IP-адресу WAN.
Тем не менее, я не могу установить соединение по локальной сети, так как он жалуется на разрыв соединения TLS. Я перепробовал несколько клиентов, и все они имеют какую-то ошибку тайм-аута. Я подозреваю, что часть проблемы может быть моей настройкой DNS. У меня есть доменное имя, которое указывает на мою глобальную сеть, и именно это я обычно использую для подключения к серверу. Но мой локальный DNS-сервер отвечает IP-адресом локальной сети для компьютера ftp. Поэтому, когда я дома, мой ноутбук устанавливает соединение ftp с 192.168.1.2, но ответ PASV - это мой WAN IP 74.xxx Теоретически мой маршрутизатор должен поддерживать обратную петлю NAT, которая отправляет трафик, исходящий из локальной сети и предназначенный для IP WAN, обратно на локальный IP, на который он пересылается. Похоже, что это нормально работает для http, и я предположил, что, поскольку клиент инициирует tcp-соединение в пассивном режиме, он должен работать и для этого. Но, может быть, я пропускаю некоторые детали маршрутизации. Может ли это быть проблемой?
Журнал клиента:
Status: Connecting to 192.168.1.2:21...
Status: Connection established, waiting for welcome message...
Trace: CFtpControlSocket::OnReceive()
Response: 220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
Response: 220-You are user number 9 of 50 allowed.
Response: 220-Local time is now 16:01. Server port: 21.
Response: 220-This is a private system - No anonymous login
Response: 220-IPv6 connections are also welcome on this server.
Response: 220 You will be disconnected after 15 minutes of inactivity.
Trace: CFtpLogonOpData::ParseResponse() in state 1
Trace: CControlSocket::SendNextCommand()
Trace: CFtpLogonOpData::Send() in state 2
Command: AUTH TLS
Trace: CFtpControlSocket::OnReceive()
Response: 234 AUTH TLS OK.
Trace: CFtpLogonOpData::ParseResponse() in state 2
Status: Initializing TLS...
Trace: CTlsSocketImpl::Handshake()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: TLS handshake: About to send CLIENT HELLO
Trace: TLS handshake: Sent CLIENT HELLO
Trace: CTlsSocketImpl::OnSend()
Trace: CTlsSocketImpl::OnRead()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: CTlsSocketImpl::OnRead()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: TLS handshake: Received SERVER HELLO
Trace: TLS handshake: Processed SERVER HELLO
Trace: CTlsSocketImpl::OnRead()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: TLS handshake: Received CERTIFICATE
Trace: TLS handshake: Processed CERTIFICATE
Trace: TLS handshake: Received SERVER KEY EXCHANGE
Trace: TLS handshake: Processed SERVER KEY EXCHANGE
Trace: TLS handshake: Received SERVER HELLO DONE
Trace: TLS handshake: Processed SERVER HELLO DONE
Trace: TLS handshake: About to send CLIENT KEY EXCHANGE
Trace: TLS handshake: Sent CLIENT KEY EXCHANGE
Trace: TLS handshake: About to send FINISHED
Trace: TLS handshake: Sent FINISHED
Trace: CTlsSocketImpl::OnRead()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: TLS handshake: Received NEW SESSION TICKET
Trace: TLS handshake: Processed NEW SESSION TICKET
Trace: TLS handshake: Received FINISHED
Trace: TLS handshake: Processed FINISHED
Trace: TLS Handshake successful
Trace: Protocol: TLS1.2, Key exchange: ECDHE-RSA, Cipher: AES-256-GCM, MAC: AEAD
Status: Verifying certificate...
Status: TLS connection established.
Trace: CControlSocket::SendNextCommand()
Trace: CFtpLogonOpData::Send() in state 5
Command: USER *****
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 331 User ******* OK. Password required
Trace: CFtpLogonOpData::ParseResponse() in state 5
Trace: CControlSocket::SendNextCommand()
Trace: CFtpLogonOpData::Send() in state 5
Command: PASS **********
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 230 OK. Current directory is /
Trace: CFtpLogonOpData::ParseResponse() in state 5
Trace: CControlSocket::SendNextCommand()
Trace: CFtpLogonOpData::Send() in state 9
Command: OPTS UTF8 ON
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 200 OK, UTF-8 enabled
Trace: CFtpLogonOpData::ParseResponse() in state 9
Trace: CControlSocket::SendNextCommand()
Trace: CFtpLogonOpData::Send() in state 10
Command: PBSZ 0
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 200 PBSZ=0
Trace: CFtpLogonOpData::ParseResponse() in state 10
Trace: CControlSocket::SendNextCommand()
Trace: CFtpLogonOpData::Send() in state 11
Command: PROT P
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 200 Data protection level set to "private"
Trace: CFtpLogonOpData::ParseResponse() in state 11
Status: Logged in
Trace: Measured latency of 3 ms
Trace: CFtpControlSocket::ResetOperation(0)
Trace: CControlSocket::ResetOperation(0)
Trace: CFtpLogonOpData::Reset(0) in state 14
Trace: CFileZillaEnginePrivate::ResetOperation(0)
Status: Retrieving directory listing...
Trace: CControlSocket::SendNextCommand()
Trace: CFtpListOpData::Send() in state 0
Trace: CFtpChangeDirOpData::Send() in state 0
Trace: CFtpChangeDirOpData::Send() in state 1
Command: PWD
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 257 "/" is your current location
Trace: CFtpChangeDirOpData::ParseResponse() in state 1
Trace: CFtpControlSocket::ResetOperation(0)
Trace: CControlSocket::ResetOperation(0)
Trace: CFtpChangeDirOpData::Reset(0) in state 1
Trace: CFtpListOpData::SubcommandResult(0) in state 1
Trace: CControlSocket::SendNextCommand()
Trace: CFtpListOpData::Send() in state 2
Trace: CFtpRawTransferOpData::Send() in state 1
Command: TYPE I
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 200 TYPE is now 8-bit binary
Trace: CFtpRawTransferOpData::ParseResponse() in state 1
Trace: CControlSocket::SendNextCommand()
Trace: CFtpRawTransferOpData::Send() in state 2
Command: PASV
Trace: CTlsSocketImpl::OnRead()
Trace: CFtpControlSocket::OnReceive()
Response: 227 Entering Passive Mode (75,85,*,*,46,161)
Trace: CFtpRawTransferOpData::ParseResponse() in state 2
Trace: CControlSocket::SendNextCommand()
Trace: CFtpRawTransferOpData::Send() in state 4
Trace: Destination IP of data connection does not match peer IP of control connection. Not binding source address of data connection.
Command: MLSD
Trace: CTransferSocket::OnConnect
Trace: CTlsSocketImpl::Handshake()
Trace: Trying to resume existing TLS session.
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: TLS handshake: About to send CLIENT HELLO
Trace: TLS handshake: Sent CLIENT HELLO
Trace: CTlsSocketImpl::OnSend()
Trace: CTlsSocketImpl::OnSend()
Trace: CTlsSocketImpl::OnRead()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: CTlsSocketImpl::OnRead()
Trace: CTlsSocketImpl::ContinueHandshake()
Trace: CTlsSocketImpl::Failure(-110)
Error: GnuTLS error -110: The TLS connection was non-properly terminated.
Status: Server did not properly shut down TLS connection
Trace: CTlsSocketImpl::OnSocketEvent(): close event received
Trace: CTransferSocket::OnClose(106)
Error: Transfer connection interrupted: ECONNABORTED - Connection aborted
Trace: CTransferSocket::TransferEnd(3)
Trace: CFtpControlSocket::TransferEnd()
Trace: CFtpControlSocket::ResetOperation(10)
Trace: CControlSocket::ResetOperation(10)
Trace: CFtpRawTransferOpData::Reset(10) in state 6
Trace: CFtpControlSocket::ResetOperation(10)
Trace: CControlSocket::ResetOperation(10)
Trace: CFtpListOpData::Reset(10) in state 3
Error: Directory listing aborted by user
Trace: CFileZillaEnginePrivate::ResetOperation(10)
Status: Disconnected from server
Trace: CRealControlSocket::DoClose(66)
Trace: CControlSocket::DoClose(66)
Trace: CFtpControlSocket::ResetOperation(66)
Trace: CControlSocket::ResetOperation(66)
Trace: CFileZillaEnginePrivate::ResetOperation(66)
Trace: CRealControlSocket::DoClose(66)
Trace: CControlSocket::DoClose(66)
Trace: CControlSocket::DoClose(66)
Trace: CFileZillaEnginePrivate::ResetOperation(0)