How to automate FTP user creation with Pure-FTPd on Mac OS X?
December 8, 2008 7:10 AM Subscribe
How to automate FTP user creation with Pure-FTPd on Mac OS X (running Apache) retrieving usernames and passwords from another http (linux) server?
I have made for a client a website with user registration feature, hosted on a shared linux hosting.
The client of the website has an internal always turned-on Mac with XAMPP and Pure-FTPd running on OS X, connected to Internet with a static IP.
In the website, I can create a button/link which connects with phpWebFTP (a nice web FTP client) installed in htdocs on the Mac server, which connects to the FTP server (pure-FTPd) on the same machine (localhost, i.e. the Mac server); the link/button can send the username, and phpWebFTP will ask for the password. No problem on this side.
Said that, I need this: when a user registers on the website (maybe not in the very same moment, even at regular intervals is good enough), an FTP account should be created on the Mac server, with same username/password used for registration.
So I need some sort of chron job, script, reading a file from the linux server, etc... well, I don't know!
I have found the following useful page on Pure-FTPd documentation:
README.Virtual-Users
Unfortunately, I need pretty detailed and straightforward instructions on what to do on the Mac side, because:
- I am not a Mac user (but I am comfortable with terminal, command-line utils and this sort of things)
- the internal Mac server is located in a pretty distant place from me
- I have a limited amount of time to put my hands on the server, after which I have to schedule a new trip
So, for the linux shared hosting php part no details needed; for the Mac server part, something like a tutorial would be very appreciated.
Thanks, sincerely
I have made for a client a website with user registration feature, hosted on a shared linux hosting.
The client of the website has an internal always turned-on Mac with XAMPP and Pure-FTPd running on OS X, connected to Internet with a static IP.
In the website, I can create a button/link which connects with phpWebFTP (a nice web FTP client) installed in htdocs on the Mac server, which connects to the FTP server (pure-FTPd) on the same machine (localhost, i.e. the Mac server); the link/button can send the username, and phpWebFTP will ask for the password. No problem on this side.
Said that, I need this: when a user registers on the website (maybe not in the very same moment, even at regular intervals is good enough), an FTP account should be created on the Mac server, with same username/password used for registration.
So I need some sort of chron job, script, reading a file from the linux server, etc... well, I don't know!
I have found the following useful page on Pure-FTPd documentation:
README.Virtual-Users
Unfortunately, I need pretty detailed and straightforward instructions on what to do on the Mac side, because:
- I am not a Mac user (but I am comfortable with terminal, command-line utils and this sort of things)
- the internal Mac server is located in a pretty distant place from me
- I have a limited amount of time to put my hands on the server, after which I have to schedule a new trip
So, for the linux shared hosting php part no details needed; for the Mac server part, something like a tutorial would be very appreciated.
Thanks, sincerely
I would compile PureFTPd with MySQL support and use that to bridge your apps together, assuming you can access your mysql server from your mac?
See: pureftpd docs
posted by mebibyte at 9:19 AM on December 8, 2008
See: pureftpd docs
posted by mebibyte at 9:19 AM on December 8, 2008
In terms of things you could look into, I'd suggest looking at SSH using public/private keys. This works well for automated scripts. (Google "ssh without passwords" for a variety of howtos.) Once you get SSH access to the mac you can start playing around with scripts.
With SSH you can run commands via SSH non-interactively. For example, you could do "ssh adminuser@macbox.somewhere.net ls -l" to get a listing of adminuser's home directory. When the keys are setup this should just exectute like it's on a local machine, not asking for a password at all.
Now, for setting this up to add accounts, I'd take a look at "useradd" - or the variation under Darwin. I see mentions of ports of it. There seems to be many different ways, all depending on things installed or versions of Darwin/OSX in use. I looked at many things when I Googled "add user from mac command line" that may be of help.
Under Linux, the "useradd" command to add a user quickly would be:
That would setup a new account called "testuser" with the name "Test User", with a home directory of "/var/www" and a password of "password". The "-N" means to not setup a new group for this user. You can also specify a group or groups, just check the man page.
The "$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1." is the output of
Running it multiple times doesn't have any effect if the user already exists, it just displays a message and exits.
Once you're up and running, with SSH working with keys, and with an admin user on the Mac, and you've figured out the right command line to use to make an account, then you'd be looking at running something like this:
Of course, the opposite could work as well, to delete a user:
There's a variety of commands in PHP for running system commands - exec() and passthru() might be of interest.
Now, this says nothing about security, so I'm inserting the standard disclaimer about this being potentially unsafe, especially considering you'll be running an admin/root level account remotely and in an automated fashion.
posted by Fat Elvis at 1:00 PM on December 8, 2008
With SSH you can run commands via SSH non-interactively. For example, you could do "ssh adminuser@macbox.somewhere.net ls -l" to get a listing of adminuser's home directory. When the keys are setup this should just exectute like it's on a local machine, not asking for a password at all.
Now, for setting this up to add accounts, I'd take a look at "useradd" - or the variation under Darwin. I see mentions of ports of it. There seems to be many different ways, all depending on things installed or versions of Darwin/OSX in use. I looked at many things when I Googled "add user from mac command line" that may be of help.
Under Linux, the "useradd" command to add a user quickly would be:
useradd -c 'Test User' -d '/var/www' -N -s '/bin/bash' -p '$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1.' testuser
That would setup a new account called "testuser" with the name "Test User", with a home directory of "/var/www" and a password of "password". The "-N" means to not setup a new group for this user. You can also specify a group or groups, just check the man page.
The "$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1." is the output of
"echo crypt('password');"
in PHP, as an example.Running it multiple times doesn't have any effect if the user already exists, it just displays a message and exits.
Once you're up and running, with SSH working with keys, and with an admin user on the Mac, and you've figured out the right command line to use to make an account, then you'd be looking at running something like this:
ssh adminuser@macbox.somewhere.net useradd -c 'Test User' -d '/var/www' -N -s '/bin/bash' -p '$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1.' testuser
Of course, the opposite could work as well, to delete a user:
ssh adminuser@macbox.somewhere.net userdel testuser
There's a variety of commands in PHP for running system commands - exec() and passthru() might be of interest.
Now, this says nothing about security, so I'm inserting the standard disclaimer about this being potentially unsafe, especially considering you'll be running an admin/root level account remotely and in an automated fashion.
posted by Fat Elvis at 1:00 PM on December 8, 2008
FTP virtual users are definitely the way to go here, especially since it sounds like you're not creating system-level accounts on the shared linux host.
The virtual-users file you linked in your question seems pretty straightforward.
Presumably you have access to all the user information for these newly-created accounts.
You'd want to write a script that runs 'pure-pw useradd' with the the correct arguments regarding where your passwd file and whatnot is on the Mac (locations, home directory structue, etc. that you would have chosen). From there, I can think of several triggers. You could periodically compare users on the linux host to those on the mac and create any missing, or you could add a hook into the linux user creation process that spawns something like "ssh mac pw-add-script username" (assuming I wasn't allowed to re-architect this, that's how I'd do it)
Otherwise, yes, you're looking at implementing a shared authentication scheme of some kind - LDAP, NIS, Kerberos, etc...all of which are drastically overkill for this scenario.
posted by namewithoutwords at 4:40 PM on December 8, 2008
The virtual-users file you linked in your question seems pretty straightforward.
Presumably you have access to all the user information for these newly-created accounts.
You'd want to write a script that runs 'pure-pw useradd' with the the correct arguments regarding where your passwd file and whatnot is on the Mac (locations, home directory structue, etc. that you would have chosen). From there, I can think of several triggers. You could periodically compare users on the linux host to those on the mac and create any missing, or you could add a hook into the linux user creation process that spawns something like "ssh mac pw-add-script username" (assuming I wasn't allowed to re-architect this, that's how I'd do it)
Otherwise, yes, you're looking at implementing a shared authentication scheme of some kind - LDAP, NIS, Kerberos, etc...all of which are drastically overkill for this scenario.
posted by namewithoutwords at 4:40 PM on December 8, 2008
Response by poster: @Fat Elvis: I prefer to avoid any ssh approach, for security reasons (I don't want hackers ssh'ing into the internal server).
@mebibyte: I prefer to avoid going into pure-ftpd compile troubles.
@cmiller: the auth info is stored on the web linux server, in a MySQL database. But I can easily write that also in a flat file, whenever a user registers, even in some encrypted form (php work). There's no problem for the mac server to read the file, I can also protect it in some way and let the php script on the mac server ovverride the protection, and decrypt the username/password pairs. This was already what I wanted to do.
My question, specifically, was (I will reformulate if it was not clear):
1) imagine the internal mac server can read every username/password reading a file on the web server;
2) imagine I can do whatever I want on the internal mac server; I already have XAMPP and Pure-FTPd running. Example: I can modify php.ini or whatever file, I can install stuff, etc. It's not a shared host, it's an always turned on mac connected to Internet with a static ip.
With 1) and 2), I would like the internal mac server to - example - scan the username/password file every hour, and create virtual ftp users accordingly (a command for virtual ftp users creation is written in the already linked README.Virtual-Users, and it's something like:
pure-pw useradd [-f ] -u [-g ]
I know this way I (i.e. phpWebFTP) will have to ask logged in users to type password for access to the ftp reserved folder (even if they are already logged in), but no problem.
But, I don't know how to do those things, especially on a mac.
Thanks to cmiller, mebibyte, Fat Elvis for your kind replies; looking forward for some other help towards cmiller's one, i.e. using a flat file accessible form the internal mac server, containing registered users' auth data.
The problem here is how to tell the mac something like: every hour, create this ftp user with this password (same username/password pair as in the web registration).
Thanks
posted by lion at 5:01 PM on December 8, 2008
@mebibyte: I prefer to avoid going into pure-ftpd compile troubles.
@cmiller: the auth info is stored on the web linux server, in a MySQL database. But I can easily write that also in a flat file, whenever a user registers, even in some encrypted form (php work). There's no problem for the mac server to read the file, I can also protect it in some way and let the php script on the mac server ovverride the protection, and decrypt the username/password pairs. This was already what I wanted to do.
My question, specifically, was (I will reformulate if it was not clear):
1) imagine the internal mac server can read every username/password reading a file on the web server;
2) imagine I can do whatever I want on the internal mac server; I already have XAMPP and Pure-FTPd running. Example: I can modify php.ini or whatever file, I can install stuff, etc. It's not a shared host, it's an always turned on mac connected to Internet with a static ip.
With 1) and 2), I would like the internal mac server to - example - scan the username/password file every hour, and create virtual ftp users accordingly (a command for virtual ftp users creation is written in the already linked README.Virtual-Users, and it's something like:
pure-pw useradd
I know this way I (i.e. phpWebFTP) will have to ask logged in users to type password for access to the ftp reserved folder (even if they are already logged in), but no problem.
But, I don't know how to do those things, especially on a mac.
Thanks to cmiller, mebibyte, Fat Elvis for your kind replies; looking forward for some other help towards cmiller's one, i.e. using a flat file accessible form the internal mac server, containing registered users' auth data.
The problem here is how to tell the mac something like: every hour, create this ftp user with this password (same username/password pair as in the web registration).
Thanks
posted by lion at 5:01 PM on December 8, 2008
Response by poster: @namewithoutwords: I was writing my reply so I've read your submission after posting. Yes, you can see in my reply the direction I would prefer following, which is what you wrote in the first part. The problem here is I don't know how to write that script, where to place it on the mac, and how to tell the mac "please do it at specified time intervals..."
Thanks go to you too.
I'll read eventual other replies tomorrow.
posted by lion at 5:10 PM on December 8, 2008
Thanks go to you too.
I'll read eventual other replies tomorrow.
posted by lion at 5:10 PM on December 8, 2008
Best answer: aha. Ok, so...
You'll need to add one "real" account on OSX for all your virtual users to share.
Create a flat file (via PHP, in your case) on the Linux server, in this format:
All you need to worry about is account, password, uid, gid, and home directory - so this would be appropriate:
(Where 9999:8888 is your "real" user:group ids. Where the password field is the output of PHP's crypt($password);. I'm not sure if you need all those ":" for the empty fields, or if that's exactly the right number of them if you do.)
Then you'll need to get that file to the mac box. There's any number of ways of doing it, but I'd suggest perhaps putting it in a password protected folder in your web root, and accessing it via HTTPS:
Now you'll need to turn that myaccounts.txt file into a FTP accounts on the mac server:
The cool thing about this is that it'll add new users, delete old users, change passwords - in short, that file becomes the current password file for Pure FTPd. You'll need to find out if /etc/pureftpd.pdb is the right location or not for OSX. It may be elsewhere.
Lastly, you'll need a script with all these commands and a cron job to run it. The script could look like this:
Save that as something.sh (on the mac) and run "chmod +x something.sh" to make it executable. (You could also make that pure-pw command into its own "if" block to test if it exits without error.)
Finally, you'll need to run "something.sh" as a cron job. It would appear that root's crontab is /private/etc/crontab - so you'll need to edit that file.
A line like this will enable the cron to run every hour at 15 minutes past the hour as roon, saving all the output of the command to a log file:
Save that crontab and watch the log.
I can't guarentee this will work out of the box, but it should get you going in the right direction.
References used:
http://jeanmatthieu.free.fr/pureftpd/
http://jeanmatthieu.free.fr/pureftpd/doc/adv/man/pure-pw.html
http://download.pureftpd.org/pub/pure-ftpd/doc/README.Virtual-Users
http://www.macdevcenter.com/pub/a/mac/2001/12/14/terminal_one.html?page=2
posted by Fat Elvis at 7:38 AM on December 9, 2008
You'll need to add one "real" account on OSX for all your virtual users to share.
Create a flat file (via PHP, in your case) on the Linux server, in this format:
account:password:uid:gid:gecos:home directory:upload
bandwidth:download bandwidth:upload ratio:download ratio:max number
of connections:files quota:size quota:authorized local IPs:refused
local IPs:authorized client IPs:refused client IPs:time
restrictions
All you need to worry about is account, password, uid, gid, and home directory - so this would be appropriate:
testuser:$1$yy7i7KfQ$DXkFMmROZC5u1EH60/jL1.:9999:8888:/path/to/ftp/:::::::::::::
(Where 9999:8888 is your "real" user:group ids. Where the password field is the output of PHP's crypt($password);. I'm not sure if you need all those ":" for the empty fields, or if that's exactly the right number of them if you do.)
Then you'll need to get that file to the mac box. There's any number of ways of doing it, but I'd suggest perhaps putting it in a password protected folder in your web root, and accessing it via HTTPS:
wget https://secretuser:secretpassword@linux.server.net/secret/myaccounts.txt
Now you'll need to turn that myaccounts.txt file into a FTP accounts on the mac server:
pure-pw mkdb /etc/pureftpd.pdb -f /path/to/myaccounts.txt
The cool thing about this is that it'll add new users, delete old users, change passwords - in short, that file becomes the current password file for Pure FTPd. You'll need to find out if /etc/pureftpd.pdb is the right location or not for OSX. It may be elsewhere.
Lastly, you'll need a script with all these commands and a cron job to run it. The script could look like this:
#!/bin/bash
if wget -q https://secretuser:secretpassword@linux.server.net/secret/myaccounts.txt; then
pure-pw mkdb /etc/pureftpd.pdb -f /path/to/myaccounts.txt
echo `date` update sucessful.
else
echo `date` update failed.
fi
Save that as something.sh (on the mac) and run "chmod +x something.sh" to make it executable. (You could also make that pure-pw command into its own "if" block to test if it exits without error.)
Finally, you'll need to run "something.sh" as a cron job. It would appear that root's crontab is /private/etc/crontab - so you'll need to edit that file.
A line like this will enable the cron to run every hour at 15 minutes past the hour as roon, saving all the output of the command to a log file:
15 * * * * root /path/to/something.sh &> /path/to/a/logfile.log
Save that crontab and watch the log.
I can't guarentee this will work out of the box, but it should get you going in the right direction.
References used:
http://jeanmatthieu.free.fr/pureftpd/
http://jeanmatthieu.free.fr/pureftpd/doc/adv/man/pure-pw.html
http://download.pureftpd.org/pub/pure-ftpd/doc/README.Virtual-Users
http://www.macdevcenter.com/pub/a/mac/2001/12/14/terminal_one.html?page=2
posted by Fat Elvis at 7:38 AM on December 9, 2008
Response by poster: Great Fat Elvis, this is the type of thing I was asking for!
I'll look carefully to everything you've written, btw I've already read it all and it has already filled a lot of missing/blurred points in my knowledge.
This is definetely the right direction, sure it will be a little tricky to accomplish but I feel I can do that.
Other details/corrections/etc. to make my work as smooth as possible are of course welcome (remember that I have a limited amount of time to put my hands on the server, then I have to schedule a new trip :(
If I succeed I'll post here the complete "tutorial" answering my question (which essentially will be an updated version of Fat Elvis' one).
Thanks very much
posted by lion at 9:04 AM on December 9, 2008
I'll look carefully to everything you've written, btw I've already read it all and it has already filled a lot of missing/blurred points in my knowledge.
This is definetely the right direction, sure it will be a little tricky to accomplish but I feel I can do that.
Other details/corrections/etc. to make my work as smooth as possible are of course welcome (remember that I have a limited amount of time to put my hands on the server, then I have to schedule a new trip :(
If I succeed I'll post here the complete "tutorial" answering my question (which essentially will be an updated version of Fat Elvis' one).
Thanks very much
posted by lion at 9:04 AM on December 9, 2008
« Older What's your idea of a romantic holidy in Europe? | Karaoke-like software that will show chords and... Newer »
This thread is closed to new comments.
Where is the auth information stored? Can you share an authentication database, instead? LDAP, or RADIUS, or NIS, perhaps?
If the web server saves its auth information in a flat file, can the FTP server read from the same file? http://www.proftpd.org/docs/modules/mod_auth_file.html
posted by cmiller at 7:31 AM on December 8, 2008