====== FTP ====== ===== SFTP-Server ===== [[::freebsd:SFTP-only mit Change Root]] ===== FTP-Server ===== ==== welches ist der sicherste FTP-Server ==== //**Antwort: "keiner"** -> weil FTP die Daten (__auch das Passwort__) unverschlüsselt überträgt, solltest Du statt dessen ''[[http://www.pro-linux.de/news/1/24569/openssh-75-freigegeben.html|SFTP]]'' verwenden; hier wird, wie bei ''SSH'', die komplette Verbindung verschlüsselt (siehe ''SCP'').// Im Gegensatz zu ''[[http://www.pro-linux.de/news/1/24569/openssh-75-freigegeben.html|SFTP]]'' und ''SCP'' bleibt bei ''[[http://www.pro-linux.de/artikel/2/1677/daten-ueber-verschluesseltes-ftp-senden.html|FTPS]]'' die Datenübertragung unverschlüsselt und schnell aber der Login wird sicher behandelt. -> [[http://www.pro-linux.de/news/1/7854/pro-linux-migration-von-ftp-zu-ftps.html|Migration von FTP auf FTPS]] Aber viele verwenden aus den unterschiedlichsten Gründen trotzdem das alte FTP-Protokoll und für die ist dieser Bertrag. Auf dieser Seite werden drei FTP-Server miteinander verglichen: [[https://systembash.com/evaluating-ftp-servers-proftpd-vs-pureftpd-vs-vsftpd/|Evaluating FTP Servers: ProFTPd vs. PureFTPd vs. vsFTPd]] Das Fatzit: - ''[[http://www.pureftpd.org/|Pure-FTPd]]'' * siehe weitere Infos zu **[[::Pure-FTP]]**: * [[https://help.ubuntu.com/community/PureFTP]] * Vorteile: * laut eigenen Aussagen, steht die Sicherheit an erster Stelle * hat die wenigsten Einträge in der //[[https://nvd.nist.gov/vuln/search|National Vulnerability Database]]// * volle Kompatibilität mit der bestehenden Spezifikation - ''[[http://vsftpd.beasts.org/|vsFTPd]]'' * siehe weitere Infos zu **[[::vsFTPd]]** * Vorteile: * laut eigenen Aussagen, ist er * sicher * extrem schnell * stabil * hat relativ wenig Einträge in der //[[https://nvd.nist.gov/vuln/search|National Vulnerability Database]]// aber mehr als Pure-FTPd * It is written by someone [[https://security.appspot.com/security/index.html|who is a vulnerability researcher]]. - ''[[http://www.proftpd.org/|ProFTPd]]'' * Eigenschaften: * muss zwingend richtig konfiguriert werden, um sicher zu sein; * hat relativ viele Einträge in der //[[https://nvd.nist.gov/vuln/search|National Vulnerability Database]]// * Vorteile: * er ist sehr stark konfigurierbar; * Konfigurationssyntax lehnt sich an Apache an; - Auch scheint ''[[https://github.com/bruceg/twoftpd|TwoFTPd]]'' einen ernsthaften Blick wert zu sein. - //''[[ftp://ftp.wu-ftpd.org/pub/wu-ftpd/|wu-ftpd]]'' ist der bekannteste, älteste und __unsicherste__ FTP-Server// ==== nativen FreeBSD 8.0 - FTP-Server (FTPD) einrichten ==== Gruppe anlegen: # pw groupadd -n programmierer -g 2000 Benutzer anlegen: # echo "geheim" | /usr/sbin/pw useradd -n fritz -u 2300 -c "Der Programmierer Fritz" -d /home/fritz -g programmierer -G admins -m -s /bin/tcsh -h 0 Passwort: . . . . . . . . . . . . geheim User-Name: . . . . . . . . . . . . fritz User-ID: . . . . . . . . . . . . . 2300 Kommentar: . . . . . . . . . . . . Der Programmierer Fritz Homeverzeichnis: . . . . . . . . . /home/fritz Gruppen-Name: . . . . . . . . . . programmierer Gruppen-Mittglied in der Gruppe: . admins Shell: . . . . . . . . . . . . . . /bin/tcsh Leider kann man die maximale Anzahl der Verbindungen nur mit dem __inetd__ einstellen, als Daemon verursacht der FTP-Dienst aber weniger Systemlast. === als Daemon === aktivieren und den FTPD konfigurieren: # vi /etc/rc.conf ... ftpd_enable="YES" ftpd_flags="-8 -h -l -M -m -t 7200 -u 007" ... starten: # /etc/rc.d/ftpd start === per Super-Server (inetd) === aktivieren und den inetd konfigurieren: # vi /etc/rc.conf ... inetd_enable="YES" inetd_flags="-wW -C 60 -l -c 20" ... den FTPD konfigurieren: # vi /etc/inetd.conf ... ftp stream tcp nowait root /usr/libexec/ftpd ftpd -8 -h -l -M -m -t 7200 -u 007 ... starten: # /etc/rc.d/inetd start === Change-Root aktivieren === == 1. Change-Root - Variante == # vi /etc/ftpchroot fritz @programmierer Der Benutzer __fritz__ kann aus seinem Homeverzeichnis nicht raus, wenn er per FTP eingelogt ist. Ebenso geht es allen Benutzern, die der Gruppe __programmierer__ angehoeren. == 1. Change-Root - Variante == Eine andere Moeglichkeit fuer Change-Root wird mit der Konsolenkonfiguration erreicht. Als erstes muss eine Klasse __ftpchroot__ angelegt werden: # vi /etc/login.conf ftpchroot|FTP Benutzerzugang:\ :ftp-chroot:\ :tc=default: jetzt muss der FTP-Benutzer noch der Klasse __ftpchroot__ zugewiesen werden: # vipw ftp:*:3000:3000:ftpchroot:0:0:FTP Benutzer:/var/ftp:/sbin/nologin Man kann den Eintrag auch in einer Bestehenden Klasse mit aufnehmen. === Verbotsliste erstellen === # vi /etc/ftpusers schultz @webgruppe Der Benutzer __schultz__ darf sich, per FTP, nicht einloggen! Ebenso dürfen sich auch alle Benutzer der Gruppe __webgruppe__ per FTP nicht einloggen! ===== FTP-Client ===== ==== mit CurlFtpFs ein Laufwerk per FTP mounten ==== mit FreeBSD 11.1-RELEASE-p11 per Mount einbinden (ftpes) > pkg install sysutils/fusefs-curlftpfs > mkdir /he > curlftpfs -o enable_epsv ftp://ftp12327624-405867:geheim@wp12327624.server-he.de /he > mount /he > ls -lha /he/ > umount /he ==== gFTP ==== Das ist ein grafischer FTP-Client von //Gnome//, der eine Bandbreitenbegrenzung ermöglicht. ==== LFTP ==== LFTP ist dafür bekannt, dass es nicht die klassischen FTP-Kommandos verwendet, sondern sich mit seinen Kommandos an BASH orientiert. Das hat den Vorteil, dass hier ein rekursives löschen von ganzen Verzeichnisbäumen mit einem einzigen Kommando funktioniert. Und das beste daren, es ist 1:1 das gleiche Komando als wenn man auf dem entfernten Rechner in einer BASH wäre: ''rm -fr Dir''. zum Beispiel kann man so ein komplettes Verzeichnis (hier ''pages'') löschen und anschließend neu übertragen: > echo "cd /wiki/data/ ; rm -fr pages ; mirror -cRF pages" | lftp ftp://ftp12345678:geheim@wp12345678.server-he.de So einfach ging es auf der CLI noch nie... :-) ==== NcFTP ==== Das ist ein sehr flexibler FTP-Client, der ursprünglich von [[::NetBSD]] stammt und mittlerweile auch zu anderen UNI*en portiert wurde. Leider funktioniert der //NcFTP 3.2.3 (July 23, 2009)// seit //FreeBSD 8.0-RELEASE// nicht mehr. Um ihn wieder ans Rennen zu bekommen, muss man ihn patchen. Was das für ein Problem ist und wo man den Patch bekommt, steht hier: [[http://www.mail-archive.com/freebsd-stable@freebsd.org/msg107277.html]] # vi server1.cfg host ftp.server.net user fritz pass geheim normales einloggen, wie mit jedem anderen auch: # ncftp -u fritz -p geheim ftp.server.net ein "ls" auf dem entfernten Rechner über das Verzeichnis "/ftp" mit langer (-l) Ausgabe: # ncftpls -u fritz -p geheim -l ftp.server.net /ftp das Verzeichnis "daten" rekursiv hochschieben: # ncftpput -u fritz -p geheim -S .tmp -m -R ftp.server.net /ftp /tmp/daten das Verzeichnis "daten" rekursiv hochschieben, alle Dateien, die Fehlerlos hochgeladen wurden, sind aus dem Verzeichnis "/tmp/daten" gelöscht worden: # ncftpput -u fritz -p geheim -S .tmp -m -R -DD ftp.server.net /ftp /tmp/daten das Verzeichnis "daten" rekursiv hochschieben (mit Konfigurationsdatei): # ncftpput -f server1.cfg -S .tmp -m -R -DD /ftp /tmp/daten ==== FTP (FreeBSD) ==== === LFTP per FTPS === * [[https://serverfault.com/questions/411970/how-to-avoid-lftp-certificate-verification-error/727003]] * ''%%lftp -e 'set ssl:verify-certificate no' ftp.default.de%%'' * [[https://superuser.com/questions/1414353/trust-server-certificate-with-lftp]] * ''%%openssl s_client -connect domain.de:21 -starttls ftp -showcerts%%'' //Die im folgenden vorgestellte Vorgehensweise wurde am Beispiel eines einfachen FTP-Zugangs bei HostEurope, am 16. Februar 2024, getestet.// damit man das Passwort nicht jedesmal von Hand eingeben muß: > touch ~/.netrc > chmod 0600 ~/.netrc > echo "machine ftp.server.net login fritz password geheim" > ~/.netrc sollte es zu dieser Fehlermeldung kommen: > echo "ls -1" | lftp ftp://fritz@domain.de ls: ls -1: Fatal error: Certificate verification: subjectAltName does not match ‘domain.de’ (A2:A6:A9:AF:AE:AC:A6:A3:A1:A7:A5:A0:A9:A1:A0:AE:A0:A3:A9:A4) wie es aussieht, brauchen wir jetzt das lftp-Konfigurationsverzeichnis und da SSL vom Remote-Host erzwungen wird, können wir es in der Konfigurationsdatei auch gleich einschalten: > mkdir -p ~/.lftp/ > echo "set ftp:ssl-auth SSL" >> ~/.lftp/rc dann kann man nachschauen, welcher Name erwartet wird: > echo QUIT | openssl s_client -connect domain.de:21 -starttls ftp -showcerts wenn es mit dem richtigen Domain-Namen immer noch nicht funktioniert, dann kann man (wenn man es hat) das richtige CA-Zertifikat mitgeben: > echo "set ssl:ca-file /etc/ssl/certs.pem" >> ~/.lftp/rc oder man schaltet diese Sicherheitsüberprüfung für diesen SSL-Fingerabdruck ab: > echo "set ssl:verify-certificate/A2:A6:A9:AF:AE:AC:A6:A3:A1:A7:A5:A0:A9:A1:A0:AE:A0:A3:A9:A4 no" >> ~/.lftp/rc === NcFTP === Da ich jetzt keine Lust habe den NcFTP zu patchen, verwende ich dann doch den FTP-Client, der bei FreeBSD (/usr/bin/ftp) schon dabei ist. Im Grunde ist der garnicht so schlecht, er kann - //~/.netrc// auslesen - für jedes einzelne Verzeichnis eine separate Bandbreitenbegrenzung (-T) - Bandbreitenbegrenzung kann für beide Richtungen (hin/zurück) sogar unterschied eingestellt werden (rate) - in Script's verwendet werden allerdings nicht ganz so schön wie der NcFTP aber dafür funktioniert er. ;-) == früher == Eine Möglichkeit diesen FTP-Client in einem Script (automatisiert) zu verwenden war diese (letztes mal getestet irgendwann zwischen 2003 und 2005): ftp ftp://fritz:geheim@ftp.server.net:/ftp/ << EOF put Datei01.txt put Datei02.txt put Datei03.txt put Datei04.txt by EOF == FreeBSD 8.0 RELEASE p3 == Als erstes schreiben wir mal die "~/.netrc": # vi ~/.netrc machine ftp.server.net login fritz password geheim # chown ich:meinegruppe ~/.netrc # chmod 0600 ~/.netrc == Variante 1 (Script) == Ich lege hier erst das Verzeichnis an und trenne die Verbindung dann wieder bevor ich das Verzeichnis mit Daten fülle. Der Grund ist der, das es ja die beiden Möglichkeiten gibt, dass das Verzeichnis noch nicht existiert oder das es schon existiert. Eigentlich müsste man erst mal nachsehen ob es schon existiert, aber den Aufwand spare ich mir. In diesem Fall wird die Verbindung sauber beendet, wenn das Verzeichnis angelegt werden konnte. Wenn es aber schon existiert, dann bricht die Verbindung ab, das ist aber egal, da es in unserem Fall ja kein Fehler ist, sondern wir vorher ja nur einen "unnötigen" Arbeitsschritt durchgeführt haben. Danach wird die Verbindung wieder aufgebaut und evtl. vorhandene Daten werden aus dem Verzeichnis gelöscht, dann kommen die neuen Daten rein. #!/bin/sh # cd /lokales/verzeichnis # ftp -p -i -N ~/.netrc ftp.server.net << EOF mdir ftp by EOF # ftp -p -i -N ~/.netrc ftp.server.net << EOF cd ftp pwd ls -l mode bin prompt mdelete * mput * by EOF Das Kommando "prompt" schaltet die Bestätigungsabfragen (Interaktionen) an bzw. aus. == Variante 2 (Script) == Dieses Beispiel ist deutlich einfacher gehalten, hier wird nur in ein Verzeichnis gewechselt, dann das aktuelle Verzeichnis und der Inhalt ausgegeben. #!/bin/sh cd /lokales/verzeichnis echo " cd /ftp pwd ls -l by " | ftp -p -i -N ~/.netrc ftp.server.net == Variante 3 (Kommandozeile) == Hier wurde das Beispiel aus "Variante 2" in einer Kommandozeilentauglichen Form dargestellt. Der Befehl "echo" muss den Parameter "-e" bekommen, damit er die Schreibweise "\n" für "Zeilenumbruch" versteht. So kann man mehrere Zeilen in einer einzigen darstellen. # echo -e "cd /ftp\npwd\nls -l\nby" | ftp -p -i -N ~/.netrc ftp.server.net ===== Skript zum Download von einem FTP-Push-Server ===== In diesem Beispiel werden in unregelmäßigen Abständen Dateien auf einem FTP-Push-Server abgelegt, der aus dem Internet immer erreichbar ist. Mit diesem Beispielskript werden die Dateien dann regelmäßig abgeholt. hier liegen die Zugangsdaten für das FTP-Programm von FreeBSD: > vi ~/etc/ftp-push.cfg # Diese Datei muss die Rechte 0400 oder 0600 haben! machine ftp.push.org login fritz password geheim dieses Skript listet alle Dateien aus der Root ("/") des FTP-Push-Server's auf: > vi ~/bin/ftp-push_ls.sh #!/bin/sh CFGDATEI="~/etc/ftp-push.cfg" # ftp -i -p -N ${CFGDATEI} ftp.push.org << EOF cd / pwd mode bin ls by EOF # Dieses Skript saugt alle Dateien, die sich auf dem FTP-Push-Server befinden und beginnt mit der Größten Datei.\\ Es wird hier nicht mit dem FreeBSD-FTP-Programm gesaugt, sondern mit dem //"wget"//, weil dieses ein paar Vorzüge biete.\\ Allerdings muss man den entsprechenden Pfad im Skript auf seine individuellen Bedürfnisse anpassen: wget -t 0 -c http://${WWWHOST}/otr/${DATEI} && TRANSFER="OK" Alle Dateien, die fehlerfrei gesaugt werden konnten, werden auf dem FTP-Push-Server gelöscht. > vi ~/bin/saug_vom_push-server.sh #!/bin/sh VERSION="v2013060900" VERSUCHE="9" # wie oft bei einem Fehler der Download versucht werden soll PATH="/bin:/usr/local/bin:/usr/bin" cd /Export/OTR/Video/Download || exit 1 #------------------------------------------------------------------------------# ### PID-Datei erstellen PIDDATEI="/tmp/$(basename ${0}).pid" if [ -e ${PIDDATEI} ] ; then echo " Das Skript '${0}' laeft schon: $(cat ${PIDDATEI}) " ls -lha ${PIDDATEI} exit 1 else date +'%F %T' >> ${PIDDATEI} fi #------------------------------------------------------------------------------# CFGDATEI="~/etc/ftp-push.cfg" FTPHOST="$(awk '/^[a-zA-Z0-9]/{print $2}' ${CFGDATEI} | head -n1)" WWWHOST="$(awk '/^[a-zA-Z0-9]/{sub("ftp","www");print $2}' ${CFGDATEI} | head -n1)" BENUTZER="$(awk '/^[a-zA-Z0-9]/{print $4}' ${CFGDATEI} | head -n1)" PASSWORT="$(awk '/^[a-zA-Z0-9]/{print $6}' ${CFGDATEI} | head -n1)" ALLEDATEIGR="$(~/bin/ftp-push_ls.sh | awk '/rw-r--r--/{print $5,$NF}' | sort -rn)" ALLEDATEIEN="$(echo "${ALLEDATEIGR}" | awk '{print $NF}')" for DATEI in ${ALLEDATEIEN} do NOCHEINMAL=Ja DURCHLAUF="${VERSUCHE}" echo "#----------------------------------------------------------------------#" while [ "${NOCHEINMAL}" == "Ja" ] do echo " #-> sauge '${DATEI}'" #echo "wget -nv -t 0 -c http://${WWWHOST}/otr/${DATEI}" echo "wget -t 0 -c http://${WWWHOST}/otr/${DATEI}" wget -t 0 -c http://${WWWHOST}/otr/${DATEI} && TRANSFER="OK" || TRANSFER="Nein" if [ "${TRANSFER}" == "OK" ] ; then echo "TRANSFER='${TRANSFER}'" GROESSEFTP="$(echo "${ALLEDATEIGR}" | fgrep "${DATEI}" | awk '{print $1}')" GROESSELOKAL="$(ls -l "${DATEI}" | awk '{print $5}')" if [ "${GROESSEFTP}" -eq "${GROESSELOKAL}" ] ; then echo "#-> delete '${DATEI}'" # ftp -i -p -N ${CFGDATEI} ${FTPHOST} << EOF cd / pwd mode bin delete ${DATEI} by EOF # FTPRETURN="$?" if [ "${FTPRETURN}" -eq "0" ] ; then NOCHEINMAL=Nein #echo "NOCHEINMAL='${NOCHEINMAL}'" echo "#-> geloescht: '${DATEI}'" /home/bin/otr-download_verschieben.sh ${DATEI} else NOCHEINMAL=Ja #echo "NOCHEINMAL='${NOCHEINMAL}'" echo "#-> konnte nicht loeschen: '${DATEI}'" fi else NOCHEINMAL=Ja #echo "NOCHEINMAL='${NOCHEINMAL}'" echo "'${GROESSEFTP}' != '${GROESSELOKAL}'" if [ "${DURCHLAUF}" -gt "0" ] ; then DURCHLAUF="$(echo "${DURCHLAUF}" | awk '{print $1-1}')" echo "DURCHLAUF='${VERSUCHE}-${DURCHLAUF}'" else NOCHEINMAL=Nein fi sleep 100 fi else NOCHEINMAL=Ja #echo "NOCHEINMAL='${NOCHEINMAL}'" #echo "TRANSFER='${TRANSFER}'" echo -n "." if [ "${DURCHLAUF}" -gt "0" ] ; then DURCHLAUF="$(echo "${DURCHLAUF}" | awk '{print $1-1}')" echo "DURCHLAUF='${VERSUCHE}-${DURCHLAUF}'" else NOCHEINMAL=Nein fi sleep 1 fi done done #------------------------------------------------------------------------------# ### PID-Datei entfernen echo "#-> BEGINN: $(cat ${PIDDATEI})" rm -vf ${PIDDATEI} echo "#-> ENDE: $(date +'%F %T')" #------------------------------------------------------------------------------# Der Aufruf erfolgt am besten so: > screen -d -m -S FTPpush ~/bin/saug_vom_push-server.sh