Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 16 to 30 of 31

Thread: FTPS vraag - voorbeelden niet compleet?

  1. #16
    @develyoy: Helaas - wat ik op Google tegenkom is niet hoopvol: WinInet FTP ondersteund geen SSL/TLS.
    @rvk: Het is eigenlijk niet de bedoeling dat er weer een pakket bijkomt - maar als het echt niet anders kan is dat uiteraard een optie.

    Het voorbeel op StackOverflow (https://stackoverflow.com/questions/...ad-of-ftp-indy) wat ik als basis gebruikt heb is niet helemaal duidelijk.
    eerst wordt de opzet aangegeven die ik heb overgenomen, maar dan de opmerking

    And then in TIdSSLIOHandlerSocketOpenSSL you set your SSL options.
    Vraag is welke, behalve ExplicitTLS? Wellicht iets met betrekking tot het certificaat of de handshaking?
    Last edited by WillemGrooters; 04-May-18 at 18:34.

  2. #17
    Ok, even helemaal back to basics.
    Je had het erover dat de Put niet werkte. Maar heb je de Get wel getest ??

    Als die ook niet werkt kan het ook nog aan instellingen op je server liggen.
    In dat geval zou je gewoon eens een testserver kunnen gebruiken.
    http://test.rebex.net/

    Met volgens stukje code krijg ik netjes de readme.txt text terug.
    Let er wel op dat je ook de OpenSSL dlls in je .exe directory moet hebben staan.
    Pak voor de 32 bit applicatie deze: http://indy.fulgan.com/SSL/openssl-1...i386-win32.zip

    Delphi Code:
    1. uses
    2.   IdIOHandler, IdIOHandlerSocket,
    3.   IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent,
    4.   IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase,
    5.   IdFTP, IdFTPCommon;
    6.  
    7. function MemoryStreamToString(M: TMemoryStream): ansistring;
    8. begin
    9.   SetString(Result, PAnsiChar(M.Memory), M.Size div SizeOf(AnsiChar));
    10. end;
    11.  
    12. procedure Test;
    13. var
    14.   IdFTP: TIdFTP;
    15.   IdSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
    16.   Stream: TMemoryStream;
    17.   Str: AnsiString;
    18. begin
    19.   Stream := TStringStream.Create;
    20.   IdFTP := TIdFTP.Create(nil);
    21.   IdSSLIOHandlerSocketOpenSSL:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    22.   try
    23.     IdFTP.IOHandler := IdSSLIOHandlerSocketOpenSSL;
    24.     IdFTP.UseTLS := utUseExplicitTLS;
    25.     IdFTP.DataPortProtection := ftpdpsPrivate;
    26.     IdFTP.Host := 'test.rebex.net';
    27.     IdFTP.Username := 'demo';
    28.     IdFTP.Password := 'password';
    29.     IdFTP.TransferType := ftBinary;
    30.     IdFTP.Passive := true;
    31.     IdFTP.Connect();
    32.     IdFTP.Get('readme.txt', Stream);
    33.     Str := MemoryStreamToString(Stream);
    34.     Showmessage(MemoryStreamToString(Stream));
    35.   finally
    36.     IdFTP.Free;
    37.     IdSSLIOHandlerSocketOpenSSL.Free;
    38.     Stream.Free;
    39.   end;
    40. end;

    (en roep dan in een OnButtonClick de test-procedure aan)

    Als dat werkt probeer dan dit stukje code met jouw ftps-server met een readme.txt in de root.

  3. #18
    Zo'n testserver is inderdaad handig - je moet 'm maar net kennen Het blijkt inderdaad aan de server te liggen, want ook hier treedt timeout op - dus conat op te nemen met de beheerder.
    Verschil is ook met FileZilla: er wordt geen medling van het certificaat gegeven, connectie doet het gewoon, zonder morren. Dat zou wel eens het punt kunnen zijn: de server waarmee ik verbining leg geeft in FileZilla bij inloggen al de medling van het onbekende certificaat; ik vermoed dat het bij het opzetten van de connectie al niet lukt juist omdat het certificaat niet herkend wordt. Ergens moet dat dan wel worden herkend, het wordt echter niet afgevangen (er wordt kennelijk ook geen exception afgevuurd)..

    (Overigens: regel 19 aangepast naar
    Code:
    Stream := TMemoryStream.Create
    - maar dat terzijde)

  4. #19
    Ja, ik had eerst een TStringStream willen gebruiken maar had het later naar een TMemoryStream gewijzigd en die create vergeten.

    Nu is het van belang dat je eens kijkt welke TLS die server allemaal ondersteund. Ik begreep dat Indy nog geen ondersteuning heeft voor de laatste OpenSSL maar het kan hier dus ook zo zijn dat je specifiek een bepaalde TLS op moet geven (b.v. sslvTLSv1).

    Dus waarschuwing in FileZilla maakt niet uit want die krijg je ook bij test.rebex.net en daar werkt dit stukje snippet in Delphi ook zonder problemen.

    Kun je eens kijken welke TLS ondersteund wordt op de server met:

    Lunux Code:
    1. nmap --script ssl-enum-ciphers -p 990 jouw_server

    Of voer op https://sslanalyzer.comodoca.com/ de server:990 in.

    Op test.rebex.net krijg ik dan dit:

    Code:
    root@space01:~# nmap --script ssl-enum-ciphers -p 990 test.rebex.net
    
    Starting Nmap 7.40 ( https://nmap.org ) at 2018-05-07 12:09 CEST
    Nmap scan report for test.rebex.net (195.144.107.198)
    Host is up (0.039s latency).
    PORT    STATE SERVICE
    990/tcp open  ftps
    | ssl-enum-ciphers:
    |   TLSv1.0:
    |     ciphers:
    |       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp521r1) - A
    |       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp521r1) - A
    |       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
    |       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
    |       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
    |     compressors:
    |       NULL
    |     cipher preference: server
    |     warnings:
    |       64-bit block cipher 3DES vulnerable to SWEET32 attack
    |   TLSv1.1:
    |     ciphers:
    |       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp521r1) - A
    |       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp521r1) - A
    |       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
    |       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
    |       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
    |     compressors:
    |       NULL
    |     cipher preference: server
    |     warnings:
    |       64-bit block cipher 3DES vulnerable to SWEET32 attack
    |   TLSv1.2:
    |     ciphers:
    |       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp521r1) - A
    |       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp521r1) - A
    |       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp521r1) - A
    |       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp521r1) - A
    |       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
    |       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
    |       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
    |       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
    |       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
    |       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
    |       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
    |     compressors:
    |       NULL
    |     cipher preference: server
    |     warnings:
    |       64-bit block cipher 3DES vulnerable to SWEET32 attack
    |_  least strength: C
    
    Nmap done: 1 IP address (1 host up) scanned in 6.19 seconds

  5. #20
    [willem@xxxxxx ~]$ sudo nmap --script ssl-enum-ciphers -p 990 xxxxxx.nl

    Starting Nmap 5.51 ( http://nmap.org ) at 2018-05-07 17:50 CEST
    Nmap scan report for xxxxxx.nl (192.168.1.163)
    Host is up (0.00012s latency).
    PORT STATE SERVICE
    990/tcp closed ftps

    Nmap done: 1 IP address (1 host up) scanned in 0.24 seconds
    [willem@xxxxxx ~]$

    Duh. port is dicht, ja, dat wil het natuurlijk niet. Maar dan zou FileZille het ook niet mogen doen... En die doet het wel.
    Bovendien is poort 990 toch voor implicitTLS, explicitTLS (die ik gebruik) gaat toch gewoon over 21? Dan krijg ik echter alleen dat die poort open is - wat te verwachten is.
    Het zou naturrlijk kunnen zijn dat er extra poorten open gezet of geactiveerd moeten worden in de server of de firewall of zoiets, maar het blijft vaag: Want FileZilla doet het gewoon, ook over poort 21, in passive mode (vereist, lijkt het...)

  6. #21
    Ja, ik had gehoopt dat die server ook gewoon over 990 de explicit zou doen maar dat is dus niet zo.

    Je zei dat je wel connectie krijgt maar dat alleen de Get niet werkt (timeout).

    Wat geeft Showmessage(IdSSLIOHandlerSocketOpenSSL.SSLSocket. Cipher.Version);
    (dan weet je welke TLS genegotiate is.)

  7. #22
    Zal ik nagaan. Waar zou dat moeten komen - na CONNECT kan natuurlijk, heeft het zin na de timeout op GET?
    Wat encoding betreft: Volgens FileZilla is op dit moment:

    Code:
    Public key algorithm: RSA 2048 bit
    Signature algorithm: RSA-SHA256
    
    Key Exchange ECDHE-RSA
    Cipher: AES-256-GCM
    MAC: AEAD
    (Dit is wel iets anders dan eerder, maar dat maakt voor het programma mogelijk niet uit - we zullen zien).

    Ik heb al wel met de beheerder overlegd. Er komt wel een connectie binnen, CONNECT doet het in elk geval. in het programma (stapsgewijs door de Indy code heen) zie ik dat ook in tweede instantie de connectie lijkt te worden opgebouwd (TLS wordt opgezet), en een aantal commando's wordt doorgegeven; AUTH TLS heb ik gezien, en ook SYST en FEAT) maar het lijkt eop dat als PASV wordt doorgegeven, de zaak stokt. In mijn Eigen code zou ik elk commando getoond hebben in een log (zoals FileZilla dat op het scherm doet) maar om nou in de Indy-code een en en ander in te bouwen lijkt me niet zo'n goed idee - of er moet een methode zijn ingebouwd om alles (buiten TLS om) te tonen zodat te zien is wat er nu eigenlijk over het lijntje gaat en welk resultaat terugkomt...Maar als het niet anders kan moet dat maar (is in ons geval ook niet zo'n problem want we werken toch met virtuele disks en ik kan er wel een maken met die logging ingebakken).

    Wireshark zal denk ik ook niet helpen (vanwege de versleuteling) maar iets is beter dan niets....

  8. #23
    Er zijn wel loggingcomponents voor Indy. Dat zijn TIdLogDebug, TIdLogEvent en TIdLogStream. Ik weet alleen niet of je daar ook echt de negotiation in terug kunt vinden (want ik denk dat dat door OpenSSL gedaan wordt).

    Overigens... wat doet ie als je Passive op false zet ??

  9. #24
    Quote Originally Posted by rvk View Post
    Overigens... wat doet ie als je Passive op false zet ??
    Wordt niet geaccepteerd - al geprobeerd...

    Showmessage(IdSSLIOHandlerSocketOpenSSL.SSLSocket. Cipher.Version);

    geeft TLSV1/SSLV3 (na FTP.Connect, want na FTP.GET heft dat geen zin (valt er toch uit met Read Timeout).

    Dan toch maar nagegaan wat er binnen Indy gebeurt: break in TIdTCPConnection.SendCMD en kijken wat er uitgestuurd wordt - in GET. Dat blijkt "PBSZ 0" te zijn en dat kon al wel eens ' hangen'

    Dat komt uit procedure TIdFTP/SendPBSZ, als FUsingSFTP of FUseTLS = UseImplicitTLS.
    HET EERSTE BLIJKT TRUE. en dat klopt volgens mij niet - dit is toch een FTPS (FTP over SSL) en geen SFTP (FTP over SSH) verbinding? Niet dat dat veel veschil maakt, er treedt nog steeds een timeout op....(Maar dat kan komen omdat dat in CONNECT al verkeerd stond)
    Enfin. toch maar eens zien of ik alles uit de connectie kan krijgen..

  10. #25
    In ieder geval is de server ook niet helemaal netjes geconfigureerd.
    (Dit is bijna zeker het probleem bij jou)

    Want op de PASV command krijg je dit:
    Antwoord: 227 Entering Passive Mode (192,168,1,163,255,185).
    Status: Server genereerde een passief antwoord met een ontraceerbaar adres. Gebruikt het serveradres in de plaats.
    (dit vetgedrukte is iets dat FileZilla doet, maar indy niet)

    Er wordt op poort 21 een verbinding gemaakt voor commando's. Die werken ook allemaal. Als je dan een PASV doet dan krijg je van de server een IP en poort terug waarop je kunt verbinden (dit is >1024).

    Dus eigenlijk had de server daar zijn eigen EXTERNE IP mee moeten geven en niet 192.168.1.163 (wat een intern adres is).

    Misschien dat FileZilla dat netjes oplost door dan toch daarvoor de server IP te gebruiken maar het kan zijn dat Indy gewoon die 192.168.1.163 probeert te gebruiken (wat dus niet gaat).

    Misschien is er een optie om dit in indy te overrulen maar dat neemt het feit niet weg dat dit in de server dus verkeerd staat.

    http://slacksite.com/other/ftp.html

    Ik vind nu net inderdaad dat dit het probleem kan zijn:
    It is the server's responsibility to provide the public IP of gateway2 in its PASV reply. If the server is not doing that, then it is not configured properly.
    TIdFTPServer has an OnPASVReply event available that allows your code to control which IP is reported to the client.
    http://atozedsoftware.newsgroups.arc...909162442.html

    Je kunt het dus zelf oplossen door in OnPASVReply de server IP goed te zetten. Maar eigenlijk hoort dit op de server zelf gedaan te worden.

  11. #26
    Quote Originally Posted by rvk View Post

    Je kunt het dus zelf oplossen door in OnPASVReply de server IP goed te zetten. Maar eigenlijk hoort dit op de server zelf gedaan te worden.
    Dat kan alleen maar aan de server kant - en dat is geen Delphi omgeving

    In elk geval heb ik al gevonden dat ik dat interne adres kan overrulen met IdFTP.PassiveUseControlHost := true, en dan wordt de data-connectie in eerste instantie wel geinigtieerd, maar ophalen sec lukt nog niet: ik krijg de melding dat dezelfde sessie gebruikt moet worden. Dat is iets wat in de server is aangezet, dus zou het kunnen zijn dat er in het programma ook iets ingesteld moet worden zodat daaraan voldaan wordt. (Dis is de default volgens de RFC en de man-pages van de server...)
    Last edited by WillemGrooters; 08-May-18 at 10:33.

  12. #27
    Quote Originally Posted by WillemGrooters View Post
    Dat kan alleen maar aan de server kant - en dat is geen Delphi omgeving
    Nee, nee. De OnPASVReply is een event van TIdFTP. Daarin kun je dus de host-IP die je van de server terugkrijgt (192.168.x.x) overschrijven naar het externe IP.

    Maar in de server moet eigenlijk geregeld worden dat niet 192.168.x.x in de communicatie meegegeven wordt maar zijn externe adres. En dat moet in de FTP-server software ingesteld worden. Dus die server is echt niet goed opgezet.

    In elk geval heb ik al gevonden dat ik dat interne adres kan overrulen met IdFTP.PassiveUseControlHost := true
    Ha, ja, die hebben ze er later bijgemaakt (in 10.1.6). Die zorgt er inderdaad voor dat de ControlHost (dus IP waarmee op poort 21 geconnect is) gebruikt wordt voor de passieve connectie voor data.

    en dan wordt de data-connectie in eerste instantie wel geinigtieerd, maar ophalen sec lukt nog niet: ik krijg de melding dat dezelfde sessie gebruikt moet worden. Dat is iets wat in de server is aangezet, dus zou het kunnen zijn dat er in het programma ook iets ingesteld moet worden zodat daaraan voldaan wordt. (Dis is de default volgens de RFC en de man-pages van de server...)
    "melding dat dezelfde sessie gebruikt moet worden"
    Welke melding is dat precies?

    Hoe weet je verder dat de data-connectie in eerste instantie wel geïnitieerd wordt?

  13. #28
    Ok, ik zou dan OnPASVreply kunnen gebruiken maar dan moet ik OP DAT MOMENT het IP adres bij de hand hebben. Het is batuurlijk wel uit het systeem te halen, maar met PassiveUseControlHost := true heb je dat helemaal niet nodig
    ik ben met je eens dat de server daarop ingesteld moet worden maar dat kan repercussies voor andere gebruikers hebben - het is een life systeem -en bij wijziging van het IP adres (niet waarschijnlijk maar toch...) moet ook de server-configuratie veranderd worden. En daar zit de beheerder natuurlijk niet op te wachten. En zo wil het ook.

    Wat het signaal betreft: De server is een vsftpd-server (op een ouidere versie van Linux), daarop is standaard ingesteld dat bij SSL/TLS verbindingen dezelfde sessie gebruikt moet worden :
    SSL connection failed, session reuse required: see require_ssl_reuse option in vsftpd.conf man page
    Dat was ook expliciet aangezet - de documentatie geeft echter al aan dat veel clients daar niet mee overweg kunnen. Dus is dat uitgezet - en dat blijkt voor mijn programma genoeg te zijn.

    Dat de data-sesssie wel geïnitieerd wordt heb ik kunnen nagaan door de (Indy) code stap voor spa te doorlopen. FTP.GET doet een RETR commando en daaraan vooraf worden onder meer "PBSZ 0" en 'PROT P" doorgegeven, daarna "PASV". Dan "RETR <bestandsnaam>" en dat geeft status 150 ("klaar voor data-transfer" - iets van dien aard) en de volgende stap leverde in eerste instantie die foutmelding op. Was voor mij de reden om dat op de server uit te zetten - waarna het bestand werd opgehaald en getoond (in het testprogramma).

    ik heb daarna de echte code van dezelfde extra regel voorzien en zowel GET als PUT werken nu naar behoren.

  14. #29
    Quote Originally Posted by WillemGrooters View Post
    Ok, ik zou dan OnPASVreply kunnen gebruiken maar dan moet ik OP DAT MOMENT het IP adres bij de hand hebben. Het is batuurlijk wel uit het systeem te halen, maar met PassiveUseControlHost := true heb je dat helemaal niet nodig
    Klopt, maar de nieuwe PassiveUseControlHost := true; is natuurlijk makkelijker dan zelf opnieuw het IP adres in een parameter zetten in de OnPASVRepry.

    ik ben met je eens dat de server daarop ingesteld moet worden maar dat kan repercussies voor andere gebruikers hebben - het is een life systeem -en bij wijziging van het IP adres (niet waarschijnlijk maar toch...) moet ook de server-configuratie veranderd worden. En daar zit de beheerder natuurlijk niet op te wachten. En zo wil het ook.
    Op zich zouden alleen interne gebruikers daarmee problemen kunnen krijgen. Want die krijgen dan na een PASV het externe adres terug. En dan moet de interne router wel een loopback functie hebben die het externe adres weer resolved naar intern.

    Wat het signaal betreft: De server is een vsftpd-server (op een ouidere versie van Linux), daarop is standaard ingesteld dat bij SSL/TLS verbindingen dezelfde sessie gebruikt moet worden :
    Ok, daar valt natuurlijk wel even op te zoeken

    Dat de data-sesssie wel geïnitieerd wordt heb ik kunnen nagaan door de (Indy) code stap voor spa te doorlopen. FTP.GET doet een RETR commando en daaraan vooraf worden onder meer "PBSZ 0" en 'PROT P" doorgegeven, daarna "PASV". Dan "RETR <bestandsnaam>" en dat geeft status 150 ("klaar voor data-transfer" - iets van dien aard) en de volgende stap leverde in eerste instantie die foutmelding op. Was voor mij de reden om dat op de server uit te zetten - waarna het bestand werd opgehaald en getoond (in het testprogramma). ik heb daarna de echte code van dezelfde extra regel voorzien en zowel GET als PUT werken nu naar behoren.
    Wat heb je nu waar uitgezet, dat het nu werkt?
    (Want dat zou natuurlijk in Indy in te stellen moeten zijn als je geen controle hebt over de server).

  15. #30
    Zo werkt het nu:

    In Delphi programma, bij het opzetten van het IdFTP object - naast server- en inloggegevens:

    Code:
    var
      IndyFTP : TIdFTP;
      IdSSLIOHandlerSocketOpenSSL1 : TIdSSLIOHandlerSocketOpenSSL;
      FZetFTPS: Boolean; // ingevuld vanuit instellingenbestand. Men kan dus schakelen. Just in case...
    
    // Code na instellen van de standard zaken voor server-, inlog- en transfer-gegevens (gebruikt voor ' normale' en secure FTP), als voor secure-FTP is gekozen:
    
     if FZetFTPS then 
     begin
      IdSSLIOHandlerSocketOpenSSL1:= TIdSSLIOHandlerSocketOpenSSL.Create(nil) ;
      IndyFTP.IOHandler := IdSSLIOHandlerSocketOpenSSL1 ;
      IndyFTP.UseTLS := utUseExplicitTLS;
      IndyFTP.DataPortProtection := ftpdpsPrivate;
      IndyFTP.PassiveUseControlHost := true;   // Dit toegevoegd ten opzichte van eerste opzet
    end;
    Aan de server kant, in /etc/vsftpd/vsftpd.conf:

    Code:
    require_ssl_reuse=NO
    (en server herstart)

Page 2 of 3 FirstFirst 1 2 3 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •