# yMPD brand new

Earlier I told you about ympd. With the version of SuperBFG7 a number of nice new features found the way to the code. Check it out!

Tagged with:
Posted in Linux, Raspberry Pi, Technik

# mount encrypted disk with systemd

I would like to share some snippets to have an encrypted HDD mounted when both the cryptdisk and the keyfile stored on a second keydisk are provided. If the keydisk is removed, the cryptdisk will be unmounted and locked automatically.

#### Prerequisites

Before starting, try cryptsetup benchmark, if it makes sense for you to encrypt. It will increase CPU load and probably lower the data rates.

#### Hands on

To start, we have to identify the drives by attributes that are probed by udev (when the drive is plugged in). We use udevadm to show the attributes and chose one or two which uniquely identify the drive (ATTR{size} or ATTRS{serial} are usually a good measure) to add them to a udev rule file:

~$sudo udevadm info --attribute-walk --name=/dev/sda1 | grep size Add those lines to a new *.rules file in /etc/udev/rules.d/ which create a symbolic link for each disk with which we can work more easily. They also trigger the systemd units . # mount cryptdisk ACTION=="add", KERNEL=="sd[a-z][0-9]", ATTR{size}=="123456789", SYMLINK+="cryptdisk_crypted", TAG+="systemd", ENV{SYSTEMD_WANTS}+="media-cryptdisk.mount" # mount cryptkey ACTION=="add", KERNEL=="sd[a-z][0-9]", ATTR{start}=="3456789", SYMLINK+="cryptkey", TAG+="systemd", ENV{SYSTEMD_WANTS}+="media-cryptdisk.mount" You can now reload the rules ~$ sudo udevadm control --reload-rules

and test whether the links /dev/cryptkey and /dev/cryptdisk_crypted are created on plugin. To be able to work effectively with systemd you need to keep in mind that the systemd units define a network (without “loops”) of dependencies. In the end we want to mount our cryptdisk (service requested by udev on plugging in the device). To be able to do that we have to unlock the disk with our keyfile. To be able to do that we have to mount the cryptkey drive to a secure location. This automatically leaves us with the task to create three unit files for systemd that set requirements from core (mounting) to shell (device plugged in). Systemd unit files feature numerous parameters that can be found in detail here.

Mount cryptkey drive via  /etc/systemd/system/root-cryptkey.mount.

[Unit] Description=Mount Cryptkey DefaultDependencies=no Conflicts=umount.target Before=umount.target StopWhenUnneeded=true

[Mount] What=/dev/cryptkey # "Where" must match the filename Where=/root/cryptkey Options=ro DirectoryMode=0400

Unlock the cryptdisk with the keyfile via /etc/systemd/system/cryptdisk-unlock.service.

[Unit] Description=cryptdisk unlock BindsTo=media-cryptdisk.mount dev-cryptdisk_crypted.device dev-cryptkey.device Requires=root-cryptkey.mount dev-cryptdisk_crypted.device After=root-cryptkey.mount dev-cryptdisk_crypted.device

[Service] Type=oneshot TimeoutStartSec=0 RemainAfterExit=yes KillMode=none ExecStart=/sbin/cryptsetup luksOpen -d /root/cryptkey/cryptdisk.key /dev/cryptdisk_crypted intenso ExecStop=/sbin/cryptsetup luksClose cryptdisk

[Install] RequiredBy=media-cryptdisk.mount

Finally: mount the cryptdisk via /etc/systemd/system/media-cryptdisk.mount.

[Unit] Conflicts=umount.target Before=umount.target BindsTo=cryptdisk-unlock.service dev-cryptdisk_crypted.device root-cryptkey.mount dev-cryptkey.device After=cryptdisk-unlock.service dev-mapper-cryptdisk.device # you may specify some unit file that depends on media-cryptdisk.mount # Wants=cryptdisk-postmount.service [Mount] What=/dev/mapper/cryptdisk Where=/media/cryptdisk Type=ext4 Options=defaults,rw,noexec,x-systemd.automount,relatime

There you go. Reload systemd with

~$sudo systemctl daemon-reload and display the logs for testing with ~$ sudo journalctl -f

Your crypted drive should now being mounted at /media/cryptdisk, when you plug both the disk and the keydisk at the same time.

Tagged with: ,
Posted in Linux, Raspberry Pi

# RPi als HDTV Streaming Server

Ein Raspberry Pi kann mit ein wenig Aufwand in eine multifunktionale Medienbox verwandelt werden. Ich habe ja früher schon über meine Liebe zum Music Player Daemon, mein Command-Keypad und jüngst über Netflix & Amazon Instant Video Addons berichtet. Ein weiterer Baustein ist die Funktionalität als HDTV Streaming Plattform.  Mein System besteht aus einem RPi3 mit OSMC einem Denon AV Receiver und einem TV mit HDMI-CEC.

Es gibt einen langen Thread im Kodinerds Forum zum Thema IPTV. Eine Liste mit freien IPTV Kanälen wird auf GitHub aktuell gehalten. Für den Gebrauch mit Tvheadend sollte die “pipe”-Liste verwendet werden.

Um mehr Funktionen als den reinen TV-Stream zu erhalten sollte die Software Tvheadend verwendet werden, die als TV-Backend z.B. auch Aufnahmen und Stream-Pausierung unterstützt. Außerdem lässt sich beispielsweise ein DVB-S2 Adapter an den rpi anschließen, der dann auch herkömmliches TV in das gleiche System einspeisen kann. Es ist auch ein raspbian Paket für tvheadend verfügbar. Die folgenden Zeilen müssen dazu zur Datei /etc/apt/sources.list hinzugefügt werden.

# tvheadend and ffmpeg
deb http://dl.bintray.com/mpmc/deb raspbianjessie stable-4.2 deb http://www.deb-multimedia.org jessie main

Um keine Warnungen bei der Installation zu erhalten, rufen wir gleich den Schlüssel für die beiden neuen Quellen ab und installieren die Pakete erst anschließend.

~$sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 5C808C2B65558117 ~$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 379CE192D401AB61 ~$sudo apt-get updhate ~$ sudo apt-get install ffmpeg tvheadend

Note: We need mmal support for hardware acceleration on the rpi. Read here how to compile ffmpeg with hwaccel. Information for tvheadend can be found here.

Nach der Installation lässt sich tvheadend per Webbrowser auf Port 9981 konfigurieren (natürlich muss 1.2.3.4 durch die ip-Adresse des rpi ersetzt werden).

http://1.2.3.4:9981/

Wie das geht, steht hier.

Jetzt fehlt nur noch der der  und ein tvheadend Client in Kodi. Der Client ist unter “Benutzer Addons” als “Tvheadend HTSP Client” anthalten und muss nur noch aktiviert werden, nachdem Benutzer und Passwort eingegeben wurden. IPTV ist jetzt möglich.

Um den Programm Guide (EPG) zu erhalten, benötigen wir das Kodinerds Repository. Die zip-Datei kann von github heruntergeladen und dann über Kodi (Settings -> Addons -> Install zip) installiert werden.

Aus diesem Repo kann nun der Dienst “Rytec EPG Downloader” installiert und konfiguriert werden.

Activation Code 3025
XMLTV Rytec 1 Deutschland/Österreich/Schweiz

Das TV Programm wird nun regelmäßig heruntergeladen. Die .gz-Datei muss nun noch für tvheadend bereitgestellt werden. Dazu sollte im tvheadend Webfrontend unter “Konfiguration -> Kanal/EPG -> EPG-Grabber-Module” das Modul “Extern: XMLTV” aktiviert werden. Das stellt uns eine Schnittstelle /home/hts/.hts/tvheadend/epggrab/xmltv.sock zur Verfügung, die durch das Programm socat mit den Daten von Rytec gefüttert werden kann. Auf OSMC ist systemd vorhanden, deswegen bietet sich eine entsprechende service-Datei an, die das nach jedem boot durchführt, nachdem tvheadend gestartet wurde (rytec2tvheadend.service). Die Datei sollte in /etc/systemd/system/ abgespeichert werden. Die Auslagerung des simplen Befehls in ein kleines Shell-Script (rytec2tvheadend.sh) ist hier besser, da sonst die gesamten EPG-Daten (mehrere MB Text) bei jedem boot in der Log-Datei landen, was unglaublich unnötig wäre. Zum Schluss muss socat noch installiert und der Dienst aktiviert werden:

~$sudo apt-get install socat ~$ chmod +x /home/osmc/rytec2tvheadend.sh ~$sudo systemctl enable rytec2tvheadend.service Vorsicht, bei der Auswahl mehrerer Quellen in Rytec treten evt. Fehler auf. Der Programmguide sollte nun (evt. nach dem Neustart) sowohl im tvheadend Webfrontend als auch in Kodi erscheinen. Alles klar? Sonst, Kommentar! Tagged with: , , , Posted in Raspberry Pi, Technik # RPi streaming station with Amazon Instant Video and Netflix With Kodi 18 and inputstream, we can finally use DRM protected streams like used by Amazon and Netflix! ### Get Kodi 18 First install OSMC on your rpi2 or rpi3 (those addons will not work on rpi1 or zero). You will need to purchase license keys for high-quality video streams and add them to your /boot/config.txt. Log in via ssh and update your system ~$ sudo apt-get update && sudo apt-get dist-upgrade

Most likely you are on Kodi version 17 (how to check?). We need Kodi 18 to work properly with Netflix and Amazon Instant Video, since from this version DRM and input stream are properly supported.

If you are still on version 17, add this line to /etc/apt/sources.list to install the Kodi 18 test builds for OSMC.

deb http://download.osmc.tv/dev/gmc-18 ./

Make sure you backup your system before proceeding. Check here for the necessary steps to upgrade. Reboot after the process has finished. You should be now on Kodi 18. Download now the repository zip-files for the Netflix Addon by asciidisco and the Instant Video Addon by Sandmann79.

~$wget https://github.com/Sandmann79/xbmc/releases/download/v1.0.2/repository.sandmann79.plugins-1.0.2.zip ~$ wget https://github.com/kodinerds/repo/raw/master/repository.netflix/repository.netflix-1.0.1.zip

and go to Settings -> Addons -> Install from zip file. After that you can install the two video addons from their respective repositories.

### Amazon Instant Video

Setup the Amazon-Addon by choosing “Playback with” as “Input Stream” and adding your login data in “Connection”.  Within the Inputstream Settings set the streaming quality to “1080p” instead of “Max”. The Addon may be unresponsible at first, since there will be a database created that takes a lot of computing power. If it crashes, try again after rebooting.

### Netflix

For Netflix to work, we have to add some crypto-package (pycryptodomex) that should usually be installable with python-pip. However this did not work for me, so I fumbled a bit, to add the dependency differently. But maybe they fixed this issue now. Just open the kodi log in you SSH session

~$tail -f /home/osmc/.kodi/temp/kodi.log and run the addon (you will have to add an account first). If everything is fine, enjoy. If on the other hand a python error is logged that tells you something about a not found Cryptodome, proceed as follows. First, we install the general crypto-package: ~$ sudo apt-get install python-crypto

Somehow the Padding.py file is requested by the Netflix-Addon, but is not installed by python-crypto, so we add it manually:

~$wget https://pypi.python.org/packages/d6/99/56ac930e35394c93440f1a6e254cf4573098503ff4c1851e820600a46a85/pycryptodomex-3.4.7.tar.gz ~$ tar -xvf pycryptodomex-3.4.7.tar.gz ~$sudo cp pycryptodomex-3.4.7/lib/Crypto/Util/Padding.py /usr/lib/python2.7/dist-packages/Crypto/Util/ At the end, we create a symbolic link “Cryptodome” because the files are expected to be there: ~$ sudo ln -s /usr/lib/python2.7/dist-packages/Crypto /usr/lib/python2.7/dist-packages/Cryptodome

You should now got rid of errors and your Netflix addon yould be able to set your account data and watch the content.

Enjoy!

Tagged with: , , ,
Posted in Raspberry Pi

If have to admit, the idea of having some small physical keyboard to bind arbitrary commands to control my Raspberry Pi came up long time ago. After that I learned that you could control the Kodi media center running on that small computer with the TV remote via CEC (HDMI control) the plan was dropped again. These days, I finally did it, because I felt like having some easy possibility to quickly pause music or shutdown the Raspberry Pi would after all be very useful.

### In short

To realize this I wrote a simple python script called command-keypad to handle my keypad inputs and map them to custom command sets. It is heavily inspired by Peter Dikant’s rpi-ola-controller.

The script is executed whenever the keypad is plugged in and stopped when removed. This is done via udev and systemd. However, if run on an OSMC Pi Box as in my case, you additionally need to hide the keypad from Kodi, otherwise the media center alone will have the power over your command pad.

### Hands on!

First, you need a couple of files, to be found in my command-keypad project on github.

Make sure you have a linux system with python installed. In particular the script needs python-evdev available in many distributions repositories. Otherwise install it via pip.

sudo pip install PyYAML evdev


Now you can run the controller with the sample configuration file:

sudo ./command-keypad.py -c conf/simpleconfig.yaml


The evdev library captures the keyboard input on device level and needs root privileges. The above command will search for all available input devices and list them:

Error: You need to specify one of the following input devices:
/dev/input/event3    ImExPS/2 Generic Explorer Mouse
/dev/input/event2    AT Translated Set 2 keyboard
/dev/input/event1    Sleep Button
/dev/input/event0    Power Button


sudo ./command-keypad.py -c conf/simpleconfig.yaml -i /dev/input/event2


The script will now listen to your keyboard inputs. Try pressing a key to execute the mapped command. If you press a key that is not mapped, the key code will be displayed, so that you can configure this key in the yaml file.

### Setup hotplugging

If you are happy with your key mappings, setup some links, so that the script is run, whenever the dedicated command keypad is connected. My OSMC system uses systemd, therefore I prepared two files which will do the trick for such a system. However, you have first to use udevadm to identify you command-keypad:

~$udevadm info --attribute-walk /dev/input/event0 | less looking at device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3.2/1-1.3.2:1.1/0003:05A4:9750.0002/input/input1/event1': KERNEL=="event1" SUBSYSTEM=="input" DRIVER=="" looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3.2/1-1.3.2:1.1/0003:05A4:9750.0002/input/input1': KERNELS=="input1" SUBSYSTEMS=="input" DRIVERS=="" ATTRS{name}=="NOVATEK USB Keypad" ATTRS{phys}=="usb-3f980000.usb-1.3.2/input1" ATTRS{uniq}=="" ATTRS{properties}=="0"  The bold attributes are well defined if you do not use several keyboards of the same kind, so we use them to setup an udevd rule to unically identify the device. Change those values in the *.rules file, provided. Be aware that udev does not support any sort of line breaks. Now link the rule file to /etc/udev/rules.d/ by issuing ~$ sudo ln -s /path/to/command-keypad/999-command-keypad.rules /etc/udev/rules.d/999-keypad.rules
~$sudo udevadm control --reload-rules  udev will trigger to execution of the command-keypad.py, so link that as well to the appropriate location (udev links our keypad at /dev/command-keypad so we don’t have to worry about device names afterwards). ~$ sudo ln -s /path/to/command-keypad/command-keypad.service /etc/systemd/system/command-keypad.service
~$sudo systemctl daemon-reload  Also set the path to your configuration layout file in command-keypad.service. Since udev will trigger the service, you don’t have to activate it within systemd. There you go. You can check whether your daemon is actually started on plugging in the keypad with ~$ sudo journalctl -f
...
Nov 19 23:09:12 pi kernel: input: NOVATEK USB Keypad as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.3/1-1.3.2/1-1.3.2:1.1/0003:05A4:9750.0016/input/input21
Nov 19 23:09:12 pi kernel: hid-generic 0003:05A4:9750.0016: input,hidraw1: USB HID v1.00 Mouse [NOVATEK USB Keypad] on usb-3f980000.usb-1.3.2/input1
Nov 19 23:09:12 pi systemd[1]: Starting command-keypad daemon...
Nov 19 23:09:12 pi systemd[1]: Started command-keypad daemon.
...
Nov 19 23:09:10 pi kernel: usb 1-1.3.2: USB disconnect, device number 17
Nov 19 23:09:10 pi command-keypad.py[1271]: Device removed. Exiting Script.


Well done. You should now have a customizable hotplugging command keyboard!

Tagged with: , ,
Posted in Linux, Technik

# Whatsapp with pidgin on Windows and Linux

I do not like Whatsapp. Not a bit. The reason is not, that it used to be very unsafe (today they claim to use a secure encryption), but rather that this affiliated company of the social media giant facebook has access to your contacts. That does not only include your own telephone number but also numbers, addresses etc. of all your friends and buisiness partners. Did you ask them, if you are allowed to give away their data? I doubt that. And although WhatsApp says that they do not store and use this data, I would doubt that. What should they hinder to do so? Who is able to keep track on that? After all, it’s facebook we’re dealing with.

But because Whatsapp is so popular, it is hard to avoid it completely. However, I found a nice compromise. You can install the software on your laptop! There is a plugin for the well-known messaging client pidgin, which works completely independently of every phone.

There is also a portable version which can be run from your pen-drive. The plugin for windows and linux can be found here. The plugin is free for linux only, but you may find a portable version of the software with WhatsApp plugin already included. But how to register without the official app? Or, if already registered, how to find username and password? That’s easy. Remember, WhatsApp is insecure. With the help of the simple python software yowsoup, you can register for WhatsApp of find your password without having the official App.

1. Download and extract the zip archive on the right side of the page.
2. Open a terminal (command line) and change to the directory of yowsoup
3. Create a file config.txt in that directory with the following content
cc=49
phone=490123456789
id=
password=
4. In the command line, run the following command to request a new confirmation code
yowsup-cli registration --requestcode sms --config config.txt
yowsup-cli registration --register <code-code> --config config.txt

Then youre done. You may add a WhatsApp account to pidgin using your phone number (as written in the config.txt file) and the received password. Of course, you have now to add contacts by yourself, because there is no address book to spy on.

After setting up the account in pidgin, you may get the message “Server closed the connection”. To circumvent this, change the default ressource in that very account to “Android-2.31.151-443” (see https://github.com/davidgfnet/whatsapp-purple/issues/73)

Be always careful in the digital country.

Tagged with: , , ,
Posted in Gesellschaft, Technik

# Set links on custom bibtex-keys with bibtex OR biblatex

Long time ago, while working on my thesis I fumbled with bibtex (do NOT do this) that creates bibliographies from *.bib files using a horrible stack-based scripting language for the styling. I wanted to have references directly linked to the matching articles in the web as many scientific journals do, see e.g. Nature Materials (hyperlink in blue):

Citation style of Nature Materials

You can do that either by using the URL directly or resolve the digital object identifier (DOI) via dx.doi.org. DOIs are very useful, if you can get them. See e.g. this article.

So my task was to implement that using bibtex (biblatex was not very common at that time). I succeeded, by introducing some linker function, named link_it, which was able to set an appropriate link on some sequence of bibtex-keys that were processed with bibtex. For technical details look at the custom style file unsrtnat_abbrv_link_it.bst on pastebin.com and search for that linker-function. Also see this article. However, here is how it looks like (hyperlink in green):

BibTeX reference using the style file unsrtnat_abbrv_link_it.bst found at http://pastebin.com/ux6eMuMq

and here is how you use it:

...
\usepackage[numbers,sort&compress]{natbib}
...
\begin{document}
...
\small{\bibliography{bibtex}}
\end{document}


Quite simple, apart from the difficulties altering the style file. However, every slight change involves stack-based horrors again, so better use the new approach with the biblatex package. For later works I used that with great success, so this is what I wanted to share with you today.

The result with the near-default style with the linker-function in it looks somewhat different from the one of natbib (hyperlink again in green):

Reference style created by the biblatex package

A bit longer is the piece of code that you have to add to your Header.tex file. But note, that you only need LaTeX-code here. Customization does not involve bibtex-style files! Okay, some of you might say that LaTeX code is also horrible to write at some deeper level. That’s true. But if you take this as an argument towards old-style bibtex, I would just say, you know nothing [John Snow].

...
\usepackage[
backend=bibtex8,
style=numeric-comp,
sorting=none,
hyperref=true,
natbib=true,
doi=false,url=false,isbn=true,
backref=false,
maxnames=4,maxcitenames=1
]{biblatex}
% bibliography file
% clear some fields
\AtEveryBibitem{
\clearfield{day}\clearfield{month}
\clearfield{issn}
\clearlist{language}
}
% define a link format for arbitrary bibtex keys
\ifhyperref{
% if hyperref is used, set doi/url links
\iffieldundef{doi}{
% if not url and not doi, print without link
\iffieldundef{url}{#1}
% use url only if doi is NOT present
{\href{\thefield{url}}{#1}}
}
% if doi is present, set a link on the key
{\href{http://dx.doi.org/\thefield{doi}}{#1}}
}
% if no hyperref, do not link
{#1}
}
% format settings
\DeclareFieldFormat[book,incollection]{isbn}{% set url link on ISBN
\DeclareFieldFormat[article]{volume}{#1}
\DeclareFieldFormat[article]{number}{\mkbibparens{#1}} % number in brackets
\DeclareFieldFormat[article]{pages}{#1} % do not add anything to pages
\renewbibmacro{in:}{} % suppress "in:"
% define a "volume(number):pages" key
\newbibmacro*{volume+number+eid}{%
\printfield{volume}
\printfield{number}
\printfield{pages}
}
\clearfield{pages} % pages used, where not intended, clear field
}
% use "et al."
\DefineBibliographyStrings{ngerman}{
....
\begin{document}
...
{\small\printbibliography}
\end{document}


I’m very hapy with this now. Another pro for biblatex is, that you only have to compile once, not twice, to update your bibliography. You may also have multiple bibtex-ressource files.

Feel free to comment or to use the code above. As always: everything CC BY-NC-SA 🙂

Tagged with: , , , ,
Posted in Technik

I blogged already about the nicest firefox addons and improving google search by using greasemonkey userscripts. Only recently, I noticed, that the click-tracking redirection by google search is not blocked anymore. To not being click-tracked, please use this userscript, Remove-Google-Redirection, instead. It works very well (at least in Firefox).

Tagged with: , , ,
Posted in Technik

# Script: notify by e-mail before running out of disk space

I just wanted to share another useful script, that can be run as a cronjob and send a warning notification via e-mail if your disk is running out of space. You may check it out on pastebin. It is supposed to work in conjunction with a small script examining the space used by trash bins on your system. You may install pydf on your system to make it more beautiful.

Tagged with: , , ,
Posted in Linux, Technik

# Management of ProFTPD users with kolab-webadmin

ProFTPD is a versatile ftp server. I recently integrated it in my Kolab 3.3 server environment, so that user access be can easily organized by the standard kolab-webadmin. The design looks as follows:

Kolab users are be able to login to ProFTPD but every user gets jailed in his own separate (physical) home directory. According to his group memberships, aditional shared folders can be displayed and accessed within this home directory.

You will need proftpd with support for ldap and virtual root environments. In Debian and Ubuntu, this is achieved via module packages:

• proftpd-mod-ldap, proftpd-mod-vroot

On other platforms you may need to compile your own proftpd.

Via kolab-webadmin I created a new organizational unit FTPGroups within parent unit Groups. Within this unit, you can now add groups of type (Pure) POSIX Group. These groups are later used to restrict or permit access to certain directories or apply other custom settings per group by using the IfGroup directive of ProFTPD.

Note, that you stick to sub-units of ou=Groups here, so that this unit will be recognized by the kolab-webadmin. The LDAP-record of such a group may look like this:

dn: cn=ftp_test_group,ou=FTPGroups,ou=Groups,dc=domain,dc=com
cn: ftp_test_group
gidnumber: 1234
objectclass: top
objectclass: groupofuniquenames
objectclass: posixgroup
uniquemember: uid=testuser,ou=People,dc=domain,dc=com


To make sure that our kolab-users and groups within the sub-unit get mapped correctly to their equivalents in the ftp-server, we have to edit the directives for mod_ldap. Just start with my working sample configuration ldap.conf on pastebin, which should be included in your main proftpd configuration.

Because we use the standard kolab ldap-schema, the users do neither posess a user nor group ID. Therefore, ProFTPD will fallback to the LDAPDefaultUID (example: ID of “nobody”) and LDAPDefaultGID (example: 10000). From the system side, a user with this combination of UID and GID should be allowed to read from (and maybe write to) your physical FTP directory tree. You can either add the user or group to your system and set the permissions accordingly or use the access control list (ACL). Since I use the acl-approach, the group with ID 10000 does not have to exist in /etc/group. You may install acl by executing

~# apt-get install acl

and mount your ftp storage device with the acl option (to be persistent add it in /etc/fstab) by executing

~# mount -o remount,defaults,noexec,rw,acl /dev/sda1 /var/ftp

To allow the access for users in our default group 10000 (for both existing and newly created files), we have to use the setfacl command. Think carefully about this. We want the users not to be able to remove one of the shared folders accidentally!

~# setfacl     -m g:10000:rx  /var/ftp/
~# setfacl -d  -m g:10000:rx  /var/ftp/
~# setfacl -d -Rm g:10000:rwx /var/ftp/*
~# setfacl    -Rm g:10000:rwx /var/ftp/*


We wanted all users to have their own home directory, which resides in /var/ftp/home/, so make sure this directory exists. To jail each user to their own home directory, change the DefaultRoot directive in your main configuration file /etc/proftpd.conf to look like

DefaultRoot  /var/ftp/home/%u


Nonexistent home directories /var/ftp/home/username will be created as requested by ldap.conf (see above). At this point, ldap users should be able to login and will be dropped in their empty home directory. Now we have to setup the directory permissions and have shared directories linked to the home directory. To achieve this we will make extensive use of the IfGroup directive. It’s very important, that the module mod_ifsession.c is the last module to load in /etc/proftpd/modules.conf! Additionally you should have lines, which load mod_vroot.c and mod_ldap.c.

Linking is very simple and works as follows:

<IfGroup ftp_test_group>
VRootAlias /var/ftp/share /share>
</IfGroup>


Very useful in terms of security is to limit the use of particular FTP-Commands to the admin group

# limit login to users with valid ftp_* groups
</Limit>
# in general allow ftp-commands for all users
<Directory />
<Limit ALL ALL FTP>
</Limit>
</Directory>
# deny deletion of files (does not cover overwriting)
<Directory />
<Limit DELE RMD>
</Directory>
~# service proftpd restart
Here you go! For testing purposes set the log level to debug and monitor the login process. Also force SSL (mod_tls.c), because otherwise everything, even passwords, will be transferred as cleartext! If you run into trouble somewhere, just let me know.