Where, when and how to create the administrator account/user for a private website?
So what I am asking is what's the preferable technique for creating that first administrator account/user. In my case it's for a private webapplication. I am talking about the account/user that will own the application and will if needed create/promote the other administrators. I guess you can this guy the root user?
Here are a few ways I encountered in other websites/webapplication.
Installation wizard:
You see this a lot in blog software or forums. When you install the application it will ask you to create an administrator user. Private webapplication will most likely not have this.
Installation file:
A file you run to install your application. This file will create the administrator account for you.
Configuration files:
A configuration file that holds the credentials for the administrator account.
Manually insert it into a database:
Manually insert the administrator info into the database.
When:
On a bootstrapping phase. Someone has suggested seeds.rb. I personally prefer to use the bootstrapper gem (with some addtions that allow me to parse csv files).
This action allows you to create a rake task which can be invoked like this:
rake db:bootstrap
This will create the initial admin user, as well as any seeding data (such as the list of countries, or a default blog format, etc). The script is very flexible. You can make it ask for a password, or accept a password parameter, if you feel like it.
How:
In all cases I use declarative_authorization in order to manage user permissions.
Your admin user must return a role called 'admin' (or whatever name you choose) on the list of roles attached to it. I usually have 1 single role per user, mainly because I can use role inheritance (e.g. admins are also editors by default). This means that on my database I've got a single field for users called "role_id". 0 is usually for the admin role, since it is the first one created.
Where:
A specific file inside db/bootstrap/users.rb (or yaml, or csv) specifies the details of a user with the admin role activated. The rake db:boostrap order parses that file and creates the user accordingly.
I see you tagged ruby on rails here. In RoR you would probably use the seeds.rb file under /your_app/db.
If you are using asp.net, I might assume you are using MSSQL or maybe Oracle. Having a stored proc that runs as an install script might do the job.
I have seen php apps using an install.php file that when run once installs the necessary data into the database and then tells the installer to delete the file before the app will run.
So there are three ways to deal with it.
If you have user accounts on your website (and I see you have them), config file with administrator's credentials is very awkward. This solution enforces you to duplicate a big part of authentication logic. Better keep the account in database.
I understand you are preparing application for yourself, not delivering it to your customers. Preparing installation wizard or installation files seems to be waste of time.
I would do the simplest - just raw insert. Pros: no extra work, same authentication mechanism as for other users. If you are using some kind of database migrations, you could create a migration which create a root account with some dummy password you can change later.
Installation wizard:
- definitvely the best approach. Clean, sure and user-friendly. Should be integrated with application installer.
Installation file:
- ok, but only if you have one and only script to run. Having more -> problems and potentially security flaws (all the folks who forget to delete this file after ...)
Configuration files:
To avoid. You are demanding user to know PHP, internals of your app, maybe server side configuration (anything above ftp can be "difficult")
Manually insert it into a database:
To avoid * 2.
In addition, two last solutions are impossible if you are using password hashing (ie. md5 or sha1 with site specific salt) - which is quite an obligation today.
Related
We're currently developing a 'sort of' e-commerce platform for our customers that are using our POS system.
This mainly exists of:
An Angular client-side
A PHP API as back-end
A MySQL database
Before I distribute the application to clients, I want to have a 'manageable' system for deploying and updating their platforms in case of code changes etc.
The initial setup would be:
Create database
Copy PHP files
Run composer
Run migrations
Modify configuration file for database credentials, salts, domain,..
Copy client side files
I was looking at Deployer for PHP, but I'm not sure how the whole database creation and config file modifications would work. I've originaly have the database creation in one of my migrations, but this would require a root db-user (or one with create permissions) and this user would need to be created as well.
The intial setup part could be done manually (it's not like it will be more than 5+ installations per week or so, but I would like to make it as simple as possible so that our support can do this instead of me every time)
The next part would be Updates.
I don't want to FTP to every server and apply changes. Updates can be both server side and client side. What would be the best way to do this:
Have a central system with all versions and registered websites at our end and let the client server daily check for a new version. If there is a new version, download all files from our server and run the migrations.
Push via deployer the new version to all clients. But this would overwrite or move the original config file with the DB credentials etc with the new version?
What if I need to add a new config setting? (application settings are stored in the database, but like the 'API' settings are within a config file.)
There will be a chance that all these client-servers will be distributed via our hosting provider, so we'll have access to all of them and they'll all be the same (for the configuration and such)
I've only written web applications used on one (server) location, so updating those were easy, for example via deploybot and such and the database setup was done manually, but now I'm stepping up my game and I want to make sure that I don't give myself more work than it should be.
Here's our case on developing an e-commerce platform - maybe you'll find answers to your questions there.
Codenetix spezializes in custom development, mostly web apps, so if you need help - let us know.
Good luck with your project!
Just as the question says... I've read up a few articles, others says just don't do it, but yet fail to mention a safe way. I know it hazardous to give it sudo access or root, but I was thinking about running a script that has root access through root.
One post was talking about a binary wrapper, but I did not fully understand it when I attempted it and when I tried to do a search to understand I didn't find anything that explain it well.
So, what would be a good-safe way? I don't even need to have a detailed explanation. You can just point me to a good source to start reading.
Thanks.
Specs:
Ubuntu Server 14.04
EDIT:
Commands I am talking about is mkdir, rmdir with an absolute path. Create user, remove user (which is why I need root) and edit some Apache files for me.
They fail to provide a safe way because, IMHO, there isn't one. Or, to put it another way, are you confident that your code that protects the create user and add user functions is cleverer than the hackers code that tries to gain access to your system via the back door you've built?
I can't think of a good reason for a web site to create a new system-level user. Usually web applications run using system users that are created for them by an administrator. The users inside your web site only have meaning for that web site so creating a new web site user gains that user no system privileges at all. That said, it's your call as to whether you need to do it or not.
In those cases where system operations are necessary a common approach is to build a background process that carries out those actions independently of the web site. The web site and that background process communicate via anything that works and is secure - sockets, a shared database, a text file, TCP-IP, etc. That separation allows you to control what actions can be requested and build in the necessary checks and balances. Of course it's not a small job, but you're not the first person to want to do this so I'd look for an existing tool that supports this administration.
We have a Ubuntu12.04+PHP+nginx setup on our servers. Our developers have access to both /usr/lib/php5/ and /var/www/ folders. We work on a lot of projects and at given time have 50-100 different apps/modules each with db active.
We would like to come up with a mechanism to secure our DB passwords with the following considerations:
The sysadmins create the password and register it somewhere (a file, or a sqlite db or some such)
The apps provide a key indicating which DB and what permissions level they want and this module returns an object that contains everything needed for the connection. Something like "user_manager.client1.ro", "user_manager.client1.rw".
The mechanism should provide the specific password to the app and hence accessible by 'www-data', but all the other passwords can't be seen unless their keys are known.
We have managed to get a prototype going for this, but the central password-providing module runs in www-data space and hence the file/sqlite can always be accessed by any other file in /var/www/ or /usr/lib/php5 and hence all passwords can be compromised.
Is there a way to set things up such that the password-providing module runs at root privileges and the app request the passwords from this? I know we can build a whole new service for this, but it seems too much to build and maintain (specially because this service becomes our single point of failure.)
Any suggestions?
Using permissions, you could do something like:
1) give one developer a user
2) chown every folder under /var/www/ to user www-data, and a specific group for that site, something like:
/var/www/site-a www-data group-a
/var/www/site-b www-data group-b
etc.
3) chmod every directory (and all subdirectory and files with -R) to 770
4) add each developer to every group for which he is actually developing.
A different approach, as I mentioned in a different answer, would be to
to provide the crypto keys via an API, when an application asks for it.
Your strusted devs would then query the API with a unique key to get the relevant credentials. The key can be mapped to a set of credentials (for devs on several projects).
If you protect the API either via a client certificate or IP filtering you will reduce the risk of data leak (if the access key is lost, you still need to be in the right network or to have the certificate to access the API). I would favor the certificate if you trust the developers (per your comment).
Simplest solution is to run your application that manages the credentials and hands them out to the developers from a different instance of the webserver (obviously listening on a different port) and then you can run that instance as a different user and tighten down the permissions so only that user has access to the secret files it needs.
But create an additional user, don't run it as root.
Under apache I'd point to suexec or suPHP. But since you don't use apache, that's not an option for you.
I'm building a self-hosted web app using CodeIgniter and I need a nice GUI-ified installer which will present the user with a form for database info, validate and test the info, write that info to the database.php config file, and then set up the DB structure.
Any tips for this? Should it be inside of CodeIgniter (as a Controller perhaps) or should it be its own thing (perhaps an 'install' folder which would be a sibling of 'application' and 'system')? Any projects I could look at for inspiration?
Obviously it's not a hard task but I just didn't want to reinvent the wheel so I thought I'd ask first.
It would be a much more integrated experience to have the settings page be within the web application.
However, you'll have to make sure that settings don't render the application unusable, since the user would then be locked out of making further changes.
This also has the added benefit of not having any further software requirements. If you build a native GUI, extra libraries would likely be needed.
I have an application that I am writing that will sit most of the CodeIgniter code outside the web directory. When the user downloads my code, they will need to extract it, then run either a bash or vbscript to set it up. There is no way of doing this from inside a web page that I can think of.
User downloads code.
User extracts code to temp directory.
User runs setup script (as root / administrator).
Script moves sections of code to appropriate places on the file system.
Script asks for credentials (DB, etc) and inserts them into appropriate file(s).
Script chmod's files and directories to appropriate permissions (some need write, some do not).
Is there any way to do this inside a webpage ?
I ended up using a pre_controller hook to do the check and redirect if necessary.
I am trying to figure out how one would start the setup of a small CMS.
I have the groundwork built, but the step of creating the database tables in mysql, should this all be done at once in a install.php file? Is there a preferred method for creating many tables at once, even if I don't need to insert data into them at this time?
You can
Import the schema file to your database prior to deploying the application
You can have a script that creates the schema
You can have a script that makes any changes to the current schema (for upgrades)
For a small CMS, I'd just keep the SQL in a schema file and import it when I need it.
You could also do a database copy from your dev -> live system. So you make the changes in the dev database as you need them and then push them to the live database. Something like SQLCompare for SQL Server works well.
Wordpress does the install.php route, where you have to enter your credentials and such for the target database and it then pushes the changes to it.
If you're going to be distributing your application for 3rd parties to install on their own servers, a very common approach is to provide (as you said) a simple install.php file. If your application is more complicated, often times an installation directory will come packaged. The user installing the application opens this in a browser, where your script typically does a few things:
Check PHP installation - verify (using function_exists()) all the required functions (and thus libraries) are installed and available. Alert the user of anything missing.
Allow the user to enter their configuration parameters - application specific settings required. Typically database hostname, username & password.
Test database connection - if successful, load initial tables. Commonly you keep your base schema file stored as a SQL file, so the application pushes this through the native mysql client, or issues the individual SQL commands directly.