I'm attempting to build an application in PHP to help me configure new websites.
New sites will always be based on a specific "codebase", containing all necessary web files.
I want my PHP script to copy those web files from one domain's webspace to another domain's webspace.
When I click a button, an empty webspace is populated with files from another domain.
Both domains are on the same Linux/Apache server.
As an experiment, I tried using shell and exec commands in PHP to perform actions as "root".
(I know this can open major security holes, so it's not my ideal method.)
But I still had similar permission issues and couldn't get that method to work either.
But I'm running into permission/ownership issues when copying across domains.
Maybe a CGI script is a better idea, but I'm not sure how to approach it.
Any advice is appreciated.
Or, if you know of a better resource for this type of information, please point me toward it.
I'm sure this sort of "website setup" application has been built before.
Thanks!
i'm also doing something like this. Only difference is that i'm not making copies of the core files. the system has one core and only specific files are copied.
if you want to copy files then you have to take in consideration the following:
an easy (less secured way) is to use the same user for all websites
otherwise (in case you want to provide different accesses) - you must create a different owner for each website. you must set the owner/group for the copied files (this will be done by root).
for the new website setup:
either main domain will run as root, and then it will be able to execute a new website creation, or if you dont want your main domain to be root, you can do the following:
create a cronjob (or php script that runs in a loop under CLI), that will be executed by root. it will check some database record every 2 minutes for example, and you can add from your main domain a record with setup info for new hosted website (or just execute some script that gains root access and does it without cron).
the script that creates this can be done in php. it can be done in any language you wish, it doesn't really matter as long as it gets the correct access.
in my case i'm using the same user since they are all my websites. disadvantage is that OS won't create restrictions, my php code will (i'm losing the advantage of users/groups permissions between different websites).
notice that open_basedir can cause you some hassle, make sure you exclude correct paths (or disable it).
also, there are some minor differences between fastCGI and suPHP (i believe it won't cause you too much trouble).
Related
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.
I have not been able to find solid information on preferred (best practices) and/or secure methods to allow php to access config or other types of files on a linux server not contained in the public web directory or owned by the apache user so I'm hoping to find some answers here.
I am a fairly competent PHP programmer but am increasingly tasked with writing web applications (most of which are not publicly accessible via the web however) that require updating, changing or adding to config files or files generated by some service or application on the server.
For instance, I need to create a web interface that will view, add or remove entries from a /etc/mail/spamassassin/white-list.cf file owned by root.
Another scenario is that I need php to parse mime messages in /var/vmail that are owned by user vmail.
These are just a couple examples, there will be other files in locations owned by other processes/users. How can I write PHP applications that securely access and manipulate these files without opening security risks?
If I were needing to implement something like this, I would probably look at using something like sudo to fine-tune permissions. I'm not a Linux CLI expert, so I'm sure there are issues that I haven't taken into account when typing this out.
I would probably determine what tasks need to be done, and would write a separate script for each task that needs to be completed. Using sudo, I'd assign the necessary level of permissions for that script only.
Obviously, as the number of tasks increase, so would the complexity and the amount of work involved. I'm not sure how this would affect you at the moment.
So far my search has shown the potential security holes that will be made while trying to perform a sudo'd command from within PHP.
My current problem is that I need to run a bash script as sudo on my work web server via PHP's exec() function. We currently host a little less than 200 websites. The website that will be doing this is restricted to only be accessible from my office's IP address. Will this remove any potential security issues that come with any of the available solutions?
One of the ways is to add the apache user to the sudoers file, I assume this will apply to the entire server so will still pose an issue on all other websites.
Is there any solution that will not pose a security threat when used on a website that has access restricted to our office?
Thanks in advance.
Edit: A brief background
Here's a brief description of exactly what I'm trying to achieve. The company I work for develops websites for tourism related businesses, amongst other things. At the moment when creating a new website I would need to setup a hosting package which includes: creating the directory structure for the new site, creating an apache config file which is included into httpd.conf, adding a new FTP user, creating a new database for use with the website CMS to name a few.
At the moment I have a bash script on the server which creates the directory structure, adds user, creates apache config file and gracefully restarts apache. That's just one part, what I'm looking to do is use this shell script in a PHP script to automate the entire website generation process in an easy to use way, for other colleagues and just general efficiency.
You have at least 4 options:
Add the apache user to the sudoers file (and restrict it to run the one command!)
In this case some security hole in your php-apps may run the script too (if they can include the calling php for example - or even bypass the restriction to your ip by using another url that also calls the script, mod_rewrite)
Flag the script with the s bit
Dangerous, don't do it.
Run another web server that only binds to a local interface and is not accessible from outside
This is my prefered solution, since the link calling the php is accessible by links from your main webserver and the security can be handled seperately. You can even create a new user for this server. Some simple server does the job, there are server modules for python and perl for example. It is not even necessary, that you enable exec in your php installation at all!
Run a daemon (inotify for example, to watch file events) or cronjob that reads some file or db-entry and then runs the command
This may be too complex and has the disadvantage, that the daemon can not check which script has generated the entry.
this might seem like a stupid question but I've Googled to no avail.
I've always thought of PHP as a language for creating dynamic database driven sites, and I've never thought about using it to move system files on the actual server (as I have never had a need to). My question is:
can a standard PHP 5.3.x.x installation move, copy or edit system files (I'm using a Linux sever as an example) around in /bin or maybe /etc?
is this a good idea/practise?
It has never occurred to me that if a malicious hacker were to be able to inject some PHP into a site, that they would effectively be granted access to the entire Linux server (and all its system files). I have only ever thought of PHP as something that operates inside the /vhosts directory (perhaps naively).
Sorry if this sounds like a stupid question, but I can't really test my theory as if my boss was to see me writing/uploading/executing a script that moved stuff around in the Linux file system I would be dead.
Thanks for your help guys! :)
PHP can to your server whatever the permissions of the user account it runs as allow it to do. PHP as a language is not restricted in any way (at least, in terms of permissions), it is the user account that is restricted.
This is why people will usually create a user for Apache/nginx/insert web server here to run as, and only give it permissions to manipulate files and directories related to the web server. If you don't give this user access permissions to /bin or /etc, it's can't do anything that will affect them.
is this a good idea/practice?
Normally not. Leave system administration to your sysadmin and not the user requesting your PHP scripts.
PHP can attempt to call many system commands to move or directly edit files on the hard disk. Whether it succeeds depends on the security settings.
Let's assume your running PHP thru apache and apache is set up to run all processes as the user www-data - a default setup for OS's like Debian. If you give the user www-data permission to edit /etc then yes, PHP can read and write to files in /etc
There is only one major drawback as you identified; security, security and security. You also better be sure that your PHP works properly as 1 wrongly written file could now take down the entire server.
I would also definitely not practice on your server behind your bosses back. Look into getting a cheap virtual machine, either hosted elsewhere or on your own machine curtsey of VirtualBox
Yes it can. Its a programming language, it can do anything.
It completely depends who is running it. If its root it can do anything. If its just a normal user bob. It can not do much outside the home /home/bob. Apache is also like bob. Apache usually runs under www-data, www, apache user names.
I mantain a custom PHP application (build for me) that is hosted in a web server. Sometimes I add new features or repair bugs, and after test in local I upload the changes to the web server. It's not a critical application (is a game), but the most of the time there are some people connected.
The steps that I make to upgrade the application:
Access via FTP (Filezilla)
Upload a .htaccess file that redirects all the people (except my IP) to a mantain.html file
Check that access is denied for other IP except mine.
Backup old code
Upload new code
Go to PhPMyAdmin
Backup DB
Execute scripts for the DB
Test that all works fine (if not -> revert the backups)
remove .htaccess file
I usually spend an average of 30 minutes doing these steps, and I'm wondering if there is any way to optimize, automatize or doing something to spend less time. Also I know that if I can automatize some steps there are less prone to have errors.
Several other answers suggest PHP-specific deployment tools, but being as I'm not very familiar with PHP, I'll offer some general tips. These suggestions may be redundant by some of the other tools already suggested, though.
First off, don't upload a new .htaccess file every time--just have two of them on your server. Perhaps call them .htaccess-permanent, and .htaccess-maintenence. Then create a symlink to the one that ought to be active. Then once you've tested that access is properly denied once, you don't have to do this manual testing phase every single time you do an upgrade.
I'd also write a shell script to do most everything for me. My new work flow would look like this:
Upload new code to server in a directory called new/
Log in to the server via shell, and execute the upgrade script
Test the new site
Run upgrade-finalize
The end.
Now for the interesting part, the upgrade script will do this:
It will delete the .htaccess symlink, and re-create it, pointing to .htaccess-maintenence.
It will copy the current code in current/ to backup/
It will back up the DB, using the exact same commands that PHPMyAdmin uses
It will move the contents of new/ (which you just uploaded) to current/
It will execute the scripts for the DB
And the upgrade-finalize script will simply:
Delete the .htaccess symlink, and re-create it, pointing to .htaccess-permanent once again
The only possibly tricky part here will be getting the exact commands that PHPMyAdmin uses to back up your database, but it's probably a simple mysqldump command, and you can probably get that info from PHPMyAdmin or some logs, or something. Sorry, I don't know more about PHPMyAdmin to help in this specific area.
Look into a deployment tool like Capistrano that allows you to automate those steps.
I usually spend an average of 30 minutes doing these steps, and I'm wondering if there is any way to optimize, automatize or doing something to spend less time.
There are many ways. For starters, steps one through eight can be done in a single shell script. You could checkout Phing, an automated deployment system. Also, you might want to delve in continuous integration for even more control over how and when the software can be deployed.
Doing this manually is, like you say, asking for trouble.
For starters, you could upload your files into a new webroot and when done, switch over the DocumentRoot in apache, leaving it available during the copy process. For any shared files you could use a symlink to a common folder (eg, uploaded images etc)
You could probably take the backup during operation as well if you don't care about consistency in the database. For migrations that doesn't "break" the functionality, you could also migrate it and test it on your new webroot with another hostname if consistency isn't a problem.
The best option is always to use multiple webservers so that you can take one offline for testing while the other one is operational, but you will still have problem with consistency, however I assume that is not an option since you don't mention it.