PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : vsftpd



strimbisch
23.12.06, 01:03
Hallo zusammen,


ich habe opensuse 10.2 und möchte mit vsftpd einen ftp-dienst anbieten.

die installation hat auch funktioniert. um die user keinen shell zugriff zu geben, habe ich in der /etc/passwd den shel zugriff entfernt. gibt es denn noch eine andere möglichkeit, wie ich das lösen könnte? am besten mit einem beispiel.


wenn sich der user anmeldet soll er immer in das gleiche verzeichnis kommen. wie kann ich das einstellen? am besten noch mit verschiedenen rechten.


grüße und besten dank

Columbo0815
23.12.06, 08:50
man vsftpd
Googel auch nach howtos für "virtual user". Das Homeverzeichnis stellst du bei deiner derzeitigen Lösung in /etc/passwd ein. Bei virtual user geht das zB über $USER. Aber mit ein wenig lesen verstehst du den Sinn dahinter und findest auch wo du das einstellen musst.

RichieX
23.12.06, 12:26
Wenn du es mit virtuellen Usern machen möchtest, hast du hier (http://www.nulldevice.de/wiki/vsftpd.html) ein HOWTO dazu. Den Systemusern musst du nicht unbedingt eine Shell geben, damit sie sich per ftp einloggen dürfen. Als shell-prg kannst du auch /sbin/nologin verwenden. Wenn ein Systembenutzer sich einloggt, kannst du Ihn gleich in sein Homedir leiten und auch dort einsperren (chroot).

RichieX

drcux
23.12.06, 12:44
/usr/share/doc/packages/vsftpd/EXAMPLE

Dort steht alles, was du brauchst.

craano
10.01.07, 21:05
Ich habe so etwas auch schon einmal realisiert.
Bei mir läuft das zur Zeit auf Ubuntu 6.10.

Es ist schon einige Zeit her, als ich diesen Server aufgesetzt habe, ich hoffe ich vergesse nichts wichtiges. Vielleicht hat ja jemand Interesse diese Lösung einmal zu testen.

Vorhaben:
Ich wollte nicht mit virtuellen Usern arbeiten.
Jeder User wird in sein ftp Daten Verzeichnis eingesperrt, zusätzlich gibt es ein gemeinsames Verzeichnis in dem alle schreiben können.
Jeder User bekommt ein automatisch generiertes README File für wichtige Infos in sein Verzeichnis kopiert.
Einfache Möglichkeit, um für einzelne Benutzer den FTP Zugang an- oder abzuschalten.
Sicherheit! Erstens vsftpd. Zweitens Kein ftp user soll sich am System anmelden dürfen.

Für alle, die noch interessiert sind, möchte ich meine Lösung kurz vorstellen:

1. Für jeden Benutuzer, der ftp Zugriff haben soll, einen System Benutzer anlegen.

2. Falls nicht vorhanden die Zeile
/bin/falsein /etc/shells hinzufügen.

3. In /etc/passwd für jeden ftp User als login shell /bin/false zuweisen. zB:

claus:x:1003:1002:/home/claus:/bin/false

4.Verzeichnisse /home/ftpsite/data und /home/ftpsite/SHARE anlegen.
In dem Verzeichnis /home/ftpsite/data findet Ihr später die ftp user Verzeichnisse. Das Verzeichnis SHARE ist das gemeinsame upload Verzeichnis.
Der Verzeichnisinhalt von /home/ftpsite muss jetzt so aussehen. (WICHTIG: Die Verzeichnisrechte entsprechend anpassen! Schreibrechte für SHARE, nur Leserechte für data!)

:/home/ftpsite# ls -al
insgesamt 16
dr-xr-xr-x 4 root root 4096 2006-12-02 23:46 .
drwxr-xr-x 8 root root 4096 2006-11-29 23:12 ..
dr-xr-xr-x 5 root root 4096 2006-12-03 00:21 data
drwxrwx--- 2 root ftpsite 4096 2007-01-10 19:33 SHARE


5.Meine angepasste und kommentierte vstpd.conf

# Example config file /etc/vsftpd.conf
#
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.
#
# READ THIS: This example file is NOT an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
# capabilities.
#
#
# Run standalone? vsftpd can run either from an inetd or as a standalone
# daemon started from an initscript.
listen=YES
#
# Run standalone with IPv6?
# Like the listen parameter, except vsftpd will listen on an IPv6 socket
# instead of an IPv4 one. This parameter and the listen parameter are mutually
# exclusive.
#listen_ipv6=YES
#
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
#local_umask=500
#
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=YES
#
# Activate logging of uploads/downloads.
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES
#
# If you want, you can arrange for uploaded anonymous files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown
# below.
#xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format
#xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a unique user which the
# ftp server can use as a totally isolated and unprivileged user.
#nopriv_user=ftpsecure
#
# Enable this and the server will recognise asynchronous ABOR requests. Not
# recommended for security (the code is non-trivial). Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore
# the request. Turn on the below options to have the server actually do ASCII
# mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
# predicted this attack and has always been safe, reporting the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#ascii_upload_enable=YES
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
ftpd_banner=Welcome to KUFriedrich@home FTP service.
#
# You may specify a file of disallowed anonymous e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
#deny_email_enable=YES
# (default follows)
#banned_email_file=/etc/vsftpd.banned_emails
#
# You may restrict local users to their home directories. See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.
#chroot_local_user=YES
#HIER NICHT AUSKOMMENTIEREN! WIRD WEITER UNTEN BEHANDELT!
#
#
#
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
#chroot_list_enable=YES
# (default follows)
#chroot_list_file=/etc/vsftpd.chroot_list
#
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
#
# Debian customization
#
# Some of vsftpd's settings don't fit the Debian filesystem layout by
# default. These settings are more Debian-friendly.
#
# This option should be the name of a directory which is empty. Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
#rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#
# This option specifies the location of the RSA key to use for SSL
# encrypted connections.
#rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key


####### Kai customization #######

## 2
## Für jeden user können individuelle Regeln erstellt werden. VORSICHT: DIESE REGELN ÜBERSCHREIBEN DIE REGELN DIESER DATEI!
## in /etc/vsftpd/$USER
user_config_dir=/etc/vsftpd/
## ENDE 2

## 3
## Jeden Benutzer ins ftp Verzeichnis chrooten
chroot_local_user=YES
## Auskommentieren,wenn nicht ins home chrootet werden soll, sondern in /home/ftpsite/$USER/
user_sub_token=$USER
local_root=/home/ftpsite/data/$USER
## ENDE 3

##UMASK uploaded files
local_umask=000

######Regel 1 als LETZTES abarbeiten! #####
## 1
##Nur User in der Userlist dürfen sich anmelden!
userlist_enable=Yes
userlist_deny=NO
userlist_file=/etc/vsftpd/vsftpd.user_list
##ENDE 1


6. Die Datei /etc/vsftpd/vsftpd.user_list anlegen und jeden Benutzer, der ftp Zugriff haben soll in die Datei packen. Pro Zeile immer einen Benutzernamen.

Dies ist eine super einfache Möglichkeit den ftp Zugriff für einzelne Benutzer an- oder abzuschalten. Im laufenden Betrieb müssen auch neue Benutzer nur hier eingefügt werden, das User ftp Daten Verzeichnis und das gemeinsame ftp upload Verzeichnis werden beim Systemstart (oder das script von Hand ausführen) automatisch angelegt! Das nenne ich Komfort.

7. Diese Perl script übernimmt die genannten Komfort Funktionen und stellt jedem ftp user sein eigenes Daten Verzeichnis und zusätzlich das gemeinsame upload Verzeichnis aller ftp user zur Verfügung:
(Habe das script mehr als nötig kommentiert, damit jeder die Funktion nachvollziehen kann. Zusätzlich verwende ich quotas, deswegen die quota Ausgabe. Wenn ihr diese Funktion nicht nutzt, dann die Ausgabe für das README file entfernen.)

#!/usr/bin/perl -w
#
#
#
#script muss mit root - Rechten ausgefuehrt werden
#
#
#Benutzer Verzeichnisse einrichten und mounten fuer FTP user beim Sysstart

################################################## ################################################## ##

###FTP user ermitteln und in @user speichern
sub user_ermitteln{
my $userlist_file= $_[0];
my @user;
my @user_file;

open(FILER,$userlist_file)
or die "Fehler beim Oeffnen der Datei: userlist_file";

while(defined(my $i = <FILER>)){ # Datei zeilenweise auslesen
push(@user_file,$i);}

my $control='#Userlisting:';
my $ii;

do {$ii=pop(@user_file);
chomp($ii);
push(@user,$ii);} until ($ii eq $control);

pop(@user);
return @user;}
###ENDE FTP user in @user gespeichert

################################################## ################################################## #####

###Pruefen, ob fuer jeden FTP user /home/ftpsite/$user/ besteht, usernamen fuer die kein Verzeichnis besteht zurueckgeben
sub verzeichnisse_pruefen{

my @user_alle = @_;
my @user_missing;
chdir "data"; #In Verzeichnis wechseln
my @folder = glob "*"; #Verzeichnis Listing einlesen
my $STRING = "" ; #Fuer Pattern Matching STRING =~ m/MUSTER/

foreach (@folder){ $STRING = $STRING . $_;} #Verzeichnislisting als STRING fuer Pattern Matching

foreach (@user_alle){
#Ueberpruefen, ob username im Verzeichnislisting vorkommt
unless ($STRING =~ m/$_/){
#print "user $_ hat kein Verzeichnis \n"; #Kontrollausgabe

push(@user_missing,$_); #User ohne Dir in array pushen
}
}

chdir ".."; #Aus Kompatibilit�tsgruenden zurueck wehcseln

return @user_missing;} #User ohne Dir zurueckgeben
###ENDE FTP user Verzeichnisse pruefen

################################################## ################################################## #######

###mkdir und chmod fuer alle user ohne dir############################################### ################################
sub dir_create{
chdir "data";

my $befehl;
my $return = 0;
#print " @_ \n"; #Kontrollausgabe
foreach (@_){
$befehl = "mkdir $_ && chown $_.$_ $_ && chmod 755 $_";
$return = system($befehl);
}

chdir "..";
return $return;}
###ENDE mkdir und chmod fuer alle user ohne dir

################################################## ################################################## #######

###readme finden, chattr -i und rm
sub readme_delete{
my ( $readme , @user ) = @_;
chdir "data";

my @folder;
my $STRING = ""; #Fuer Pattern Matching STRING =~ m/MUSTER/

foreach (@user){
$STRING = "";
chdir "$_";

@folder = glob "*"; #Verzeichnis Listing einlesen
foreach (@folder){$STRING = $STRING . $_;} #Verzeichnislisting als STRING fuer Pattern Matching

if ($STRING =~ m/$readme/) {system ("chattr -i $readme && rm -rf $readme");}

chdir "..";
}

chdir "..";
return;}
###readme.txt loeschen

################################################## ################################################## #######

###readme erstellen, chattr +i
sub readme_create{
chdir "data";

my ($readme , @user) = @_;
foreach (@user){
chdir "$_";
system("echo Willkommen auf XXX.homeunix.net dem FTP Server von XXX > $readme");
system("echo >> $readme ");
system("echo username: $_ >> $readme");
system("echo >> $readme");
system("echo This is your root directory. Here you have write acces and you only can read the files within this directory. >> $readme");
system("echo In the SHARE directory all other FTP users of this server have read AND write acces. So this is the right place to share files with them. >> $readme");
system("echo Do not act illegally on this server! All your actions are being logged! >> $readme ");
system("echo Be aware that FTP is an unencrypted protocol, your are not allone out there in the web. >> $readme");
system("echo Both your data and password transmission is in clear text! Maybe a bunch scumbacks are loitering around and are sniffing your files! >> $readme ");
system("echo >> $readme ");
system("echo DO NOT UPLOAD ANY ILLEGAL FILES OR MISSION CRITICAL DATA! >> $readme");
system("echo RESPECT THE COPYRIGHTS! >> $readme");
system("echo >> $readme ");
system("echo Diskspace on this server is quoted: >> $readme ");
system("quota -u $_ -svw >> $readme");
system("echo >> $readme ");
system("echo Now, have a nice day, $_ >> $readme");
system("echo >> $readme ");
system("echo >> $readme ");
system("echo This site is served by: vsFTPd >> $readme");
system("echo -n Running on: >> $readme"); system("uname -srmo >> $readme");
system("echo >> $readme ");
system("echo -n This is an autogenerated file, last modified: >> $readme "); system("date >> $readme");
system("echo >> $readme ");
system("echo >> $readme ");
system("echo http://www.linuxforen.de/forums/showthread.php?t=228448&highlight=vsftpd >> $readme");
system("echo >> $readme ");

system("chattr +i $readme");


chdir "..";
}

chdir "..";
return;}
###ENDE readme erstellen

################################################## ################################################## #######

###mount_SHARE
sub mount_SHARE{
my ($share , @user) = @_;
chdir "data";

#Wenn SHARE nicht vorhanden, dann erstellen
my @folder;
my $STRING = ""; #Fuer Pattern Matching STRING =~ m/MUSTER/

foreach (@user){
$STRING = "";
chdir "$_";

@folder = glob "*"; #Verzeichnis Listing einlesen
foreach (@folder){$STRING = $STRING . $_;} #Verzeichnislisting als STRING fuer Pattern Matching

unless ($STRING =~ m/$share/) {system ("mkdir $share && chmod 700 $share");print "SHARE f�r $_ erstellt \n";}

chdir "..";
}
#SHARE erstellen ENDE

chdir "..";

#SHAREs bind mounten
foreach (@user) {
#ZUR SICHERHEIT
system ("umount ./data/$_/SHARE ");
#ZUR SICHERHEIT
system ("mount -o bind,rw ./SHARE ./data/$_/SHARE ");
}

#SHAREs mounten ENDE

return;}
###ENDE mount_SHARE

################################################## ################################################## #######

####Start Programmablauf

#userlist_file setzen
my $userlist_file = "/etc/vsftpd/vsftpd.user_list";
#readme file setzen
my $README = "XXX.homeunix.net.readme.txt";
#SHARE Ordner =
my $SHARE = "SHARE";
#In den ftpsite Ordner wechseln
chdir "/home/ftpsite/";

#Alle User aus userlist_file=vsftpd.user_list ermitteln
my @user = user_ermitteln($userlist_file);
#print " 1 @user \n \n"; #Kontrollausgabe

#Verzeichnisse ueberpruefen Rueckgabe array enthaelt alle User ohne Dir
my @dir_fehl = verzeichnisse_pruefen(@user);
#print "2 @dir_fehl \n"; #Kontrollausgabe

#mkdir und chmod f�r alle user ohne dir
my $ru = dir_create(@dir_fehl);
#print "3 $ru \n"; #Kontrollausgabe

#Pruefen, ob /$user/readme.txt besteht, wenn dann cgattr -i und rm
readme_delete($README, @user);

#README erstellen#
readme_create($README , @user);

#SHARE mounten, pruefen ob /$user/SHARE existiert, sonst erstellen und chmod
mount_SHARE($SHARE,@user);

#READ Verzeichnis einrichten

#ZUR SICHERHEIT vsftpd --restart
system ("/etc/init.d/vsftpd restart");




print "\n"; #Letzter Zeilenumbruch

8.Das script muss bei jedem Systemstart ausgeführt werden. Ich verwende dafür /etc/rc.local. Einfach das script mit den richtigen Pfadangaben dort eintragen.

9.Wenn in /etc/vsftpd/vsftpd.user_list neue user eingefügt oder entfernt werden, dann muss das script erneut ausgeführt werden. Wenn die vsftpd.conf oder /etc/vsftpd/$USER verändert wurden, dann muss der vsftpd Server neu gestartet oder zumindest die Konfiguration neu eingelesen werden. (/etc/init.d vsftpd restart oder /etc/init.d vsftpd reload)

10. Anmerkungen:
Dies ist eine ungewöhnliche doch sehr einfache Lösung der eingangs genannten Aufgaben.
Benutzer, die ftp Zugang haben sollen einfach in /etc/vsftpd/vsftpd.user_list eintragen. Das Daten Verzeichnis des users und das gemeinsame Upload Verzeichnis wird dann automatisch (per script) zur Verfügung gestellt.
Wenn der ftp Zugang des users wieder entzogen werden soll, dann den Benutzernamen aus /etc/vsftpd/vsftpd.user_list wieder löschen.
Zusätzlich bleibt die Möglichkeit für jeden ftp Benutzer individuelle Regeln zu erstellen. Dazu dann /etc/vsftpd/$USER verwenden. So können die Vorgaben der vsftpd.conf auf user Basis überschrieben werden. Wenn gewünscht bleibt für ausgesuchte User die Möglichkeit sie in ihr Home Verzeichnis zu chrooten (Meiner Meinung nach nicht empfehlenswert).
Zur Sicherheit: Ich benutze ausschließlich Linux eigene Sicherheitsfeatures, für Schreibrechte und Zugang.
- Ein Anmelden der ftp user am System wird durch Punkt 3 verhindert!
- Jeder ftp user ist in seinem Datenverzeichnis eingesperrt!
- Schreib- bzw Leserechte werden durch die Linuxdateirechte gesteuert!

Ich freue mich auf Eure Anregungen zur Umsetzung und Verbesserungsvorschläge.

Falls diese Lösung hier viele Freunde finden sollte, schreibe ich bei Gelegenheit ein ausführliches HOWTO.

Wenn ihr diese Lösung nachbaut und umsetzt würde ich mich auf einen Link auf diesen thread (oder das mögliche HOWTO) sehr freuen.

So, ist nun doch alles viel länger geworden, als ich dachte.
Viel Vergnügen.

Grüße.
craano.

Columbo0815
11.01.07, 09:47
Anregung und Verbesserungsvorschläge:
Warum willst du nicht mit virtuellen Usern arbeiten? Genau für dein Vorhaben finde ich (IMHO) das die elegantere Lösung.

craano
11.01.07, 14:54
Nun, ich wollte einfach mal die Möglichkeiten der vsftpd.conf einmal ausreizen. Als ich diesen Server damals aufgesetzt habe, hatte kurz überlegt zu einem anderen ftp Server zu wechseln, da ich vieles vorhatte, was nicht mit vsftpd zu realisieren schien. Allerdings war ich bis dato sehr zu Frieden und gerade die Einfachheit der Konfigurationsdatei gefiel mir sehr gut.

Besonders interessant finde ich die Kombination von:

user_config_dir=/etc/vsftpd/
user_sub_token=$USER
local_root=/home/ftpsite/data/$USER
userlist_enable=Yes
userlist_deny=NO
userlist_file=/etc/vsftpd/vsftpd.user_list

Jetzt ist vieles möglich, was eigentlich nur mit virtuellen usern geht (Konfiguration auf user Basis, in verschiedene Verzeichnisse einsperren, gemeinsames Verzeichnis bestimmter oder aller user, etc).

Ich brauchte mich nicht an die Konfiguration eines anderen ftp Servers gewöhnen und mich auch nicht mit virtuellen usern auseinandersetzen. Damit konnte meine Neugier meine Faulheit befriedigen. :ugly:

Mit dem obigen Posting wollte ich im Grunde nur mal einen anderen Weg zeigen wie es auch geht.

Das kleine script war nur ein Nebenprodukt, anfangs wollte ich nur die SHARE Verzeichnisse automatisch bindend mounten.

Ganz im Sinne von Larry Wall: "There is more than one way to do it"

BTW dieser Server läuft auf meinem kleinem Heimserverchen sehr zuverlässig und ist über DynDNS auch von außen erreichbar.

Grüße.
craano.