Run PHP Application on non apache port, with non-apache user - php

We have a PHP application which automates script commands. Many of these are through web interfaces. I want this php application user to be running lots of cli and ssh commands, so I dont really want www-data doing it, as it would involve changing lots of script files to www-data executable permissions, and we want scripts to be entered into web interfaces.
This application is cross-operating system. Ideally on anything that php runs on, but win, mac,
The important things that we need to be able to do are (I think) ...
1) Have a Web Server (It's currently Apache, and that's working cross os so that would be great), that is running under normal settings, normal user, reverse proxied to the below application on te same server.
2) Have a PHP application on a different port, running as its own user that can do whatever it wants.
The ability to just run
php -S localhost:8000
As is available in the built in php web server seems ideal for this. So...
1) Is it safe to use the PHP built in Web Server if it's behind an apache proxy? I'm assuming the fact we are proxying over the entire request anyway means no, since it says not to.
2) Is there another Web Server/PHP Server that can easily do this?
3) Is there a way of running two apache processes to do this?
4) Am i doing this the wrong way entirely? There's another app I know that does it like that, but a Java app and the whole process is started and owned by a non apache user.
Thanks in advance

Apache 2.4 + php-fpm + mod_proxy_fcgi will suit you just fine.
(to elaborate for the downvote -- php-fpm allows the PHP process to run as a separate daemon under its own userid which is exactly the privilege separation requested here)

Related

Managing Debian Services from PHP

I am making an application for school but i need to be able to manage some Services running on my Debian 7 machine. I'm running "nginx" and "PHP5-FPM" so PHP 5.4. but how can I restart or stop for example "nginx" from my PHP file? i tried
exec("/etc/init.d/nginx stop");
Also I tried
shell_exec("/etc/init.d/nginx stop");
but no result php returns me:
Stopping nginx: nginx
Thanks in advance
You need to be root to restart these services, and unless your web service (like Apache) is running as your site(s) as root, this isn't going to work. There are a couple of options at your disposal, the best one would likely depend on your situation.
You can create a two-layered approach where the front-end (run by your web server) issues the commands, and the back-end is a service running as root that executes them. This could also add a layer of security as the back-end could sanitize the commands before they're executed. The communication between the front-end and back-end could be any number of things, such as a file that the front-end writes to and the back-end reads from every few seconds, or you could go with WebSockets and make it real-time.
You could run an additional instance of your web server as root that handles just this task. You would definitely want to run this over SSL, and it's somewhat risky since if someone could inject code into one of your pages, their code would be running on your server as root.

LAMP Web Server: Executing Application on Server Side can't detect USB device

I have set up a LAMP Web Server and I am looking to run an application on the server side when the client clicks a button on the servers web interface. This application will look for a certain USB Device, by Serial Number, open it up and send a packet of bytes to the device.
I have an index.html, which only has a button with an action to call my test.php file which uses shell_exec() to call my application.
When the application is invoked through the web interface, the application writes out an error indicating that it couldn't open the USB Device (this a built in error for this application, so the application works, it just can not locate the usb device).
But when I invoke the application via the Terminal, the application finds the usb device and writes to it no problem.
I am looking for some advice! Simply is what I'm doing feasible? If so, how can I get the application to find the usb device when invoked via the web interface? I have a feeling it has something to do with permissions, you never know.
test.php:
<?php
echo shell_exec("/home/pi/FDTI_test/FDTI_test_application");
?>
NOTE:
The usb device is connected, works great with its driver, and is connected to the server via usb.
The application works when invoked via the terminal on server side, but not when invoked via web interface.
I think your on the right track with this being a permissions issue.
In a typical LAMP stack, the php process runs as a module in the apache process, unless you've configured it differently. In my server OS of choice, the php process runs as the user 'www-data' by default.
Probably the easiest solution would be to give sudo permission to your web user account, and set the sudoers file to NOPASSWD. This is very insecure, so only do this in rare cases.
<?php echo shell_exec("sudo /home/pi/FDTI_test/FDTI_test_application"); ?>
The next easiest option is to give the web user account permission to write to the USB device directly. Depending on your distribution, you may only need to add the user to the 'adm' group.
sudo usermod -a -G adm www-data
Again, this may not be the most secure method, but more secure than the first option.
Lastly, you could look into the hardest solution which would be to install a patched version of apache which allows suexec. This is about as equally as insecure as the second option, but much more difficult to implement. (I would have included a link to a tutorial, but I'm limited to 2 links as this is my first answer.)
Hope This Helps!

php dev/testing servers

I need a simple "development" server for php, e.g. not apache.
In a modern environment, such as node.js, I can run node server.js inside any folder, and it will run as a server running the site specified by server.js. I can then run another node process from a different folder, and the two servers will never interfere or get in each other's way.
Is there a similar setup for php?
With apache, it seems to me that I need to "configure" the server ahead of time; I can't just drop into some folder and serve its content on some arbitrary port.
I want a command that I can use to run a php server from inside some folder, with minimum amount of configuration, for the purpose of being a development/testing only server.
For instance, suppose this server is called sps, then, I should be able to:
cd ~/code/proj1
sps
Perhaps it could require a simple config file, sps.conf that specifies the port number the server should listen to, plus maybe information about the database connection; but nothing more.
Does such a tool exist for php?
With the current version of PHP (< 5.4), you indeed have to configure a webserver (Apache, nginx, ...) to serve the directory in which you'll have your website -- the directory in which you'll work.
Generally, though, you'll only have a couple of websites, which means you won't have to re-configure your webserver too often.
And if you often have to create / test some small scripts, just create an Apache VirtualHost that points to some tests directory, in which you'll put all your test scripts (I have exactly that on my computer).
With PHP 5.4 (currently in alpha -- so not to be used on a production server just yet ^^), you'll have a built-in web server, which should pretty much answer your question.
try XAMPP Lite version http://www.apachefriends.org/en/xampp-windows.html

Running exec as a different user

Is it possible to run exec() as a a different user (on my box it runs as www-data). I wish to execute a script that needs access to files that are not owned by www-data.
If you have access to the server's configuration (assuming it's Apache), you might consider using suPHP. In a virtual host's configuration you can explicitly set the user and group for which a PHP script is executed:
<VirtualHost 192.168.1.1:80>
...
suPHP_UserGroup user group
...
</VirtualHost>
This setting is available for suPHP configurations built with the --with-setid-mode=paranoid option.
Another way to change the user ID would be posix_setuid() for which appropriate privileges are required. That would mean running your PHP scripts as root, which is a serios security issue.
I had a similar requirement some years ago that required a few PHP scripts to talk to a serial port. The first serial port is typically /dev/ttyS0, owned by root and in the group dialout.
For my initial setup, I added my apache user to the group dialout. The PHP scripts were able to directly talk to the serial port with no problem. However, only one instance of a script could open the serial port at any one time, so this solution could not work.
I then created a daemon that provided a layer between the serial port and the PHP scripts. The PHP scripts would talk to the daemon via a named pipe, and the daemon would then format the requests and pass it onto the serial port - doing a bit of caching along the way.
So, either add www-data, or whatever your apache user is, to the group that owns those files, giving group execution permissions, or use a proxy like I had. If security concerns you, then I'd go with the latter.
No, not directly. If you are on a linux machine and have the rights, you can set the set the setuid bit on your file.
Keep in mind that the webserver runs as a different user for a reason. It is a very important security mechanism and by working around it, you might cause a security vulnerability.
You can change the user under which your server runs. This can be easily done using the windows version of apache (apache runs there as service and it is easy to configure the user under which apache runs).
Which server plattform do you use?

Deploying Django with no CGI available?

I need to deploy a Django project on a shared server which I have no root access for, and no administration capabilities whatsoever.
Each user on the server has a dedicated directory from which Apache serves that users files (public URL would be /~username/).
Problem is, Apache on this server has no CGI capabilities, no mod_python, no mod_wsgi. I can work with PHP, however.
What hacks do I have to deploy a Django project on this server, maybe employing PHP somehow?
This is in no way a production scenario, and any hack you can think of which will work would be great. Ignore any performance or scalability factors - this is only a POC.
Without mod_python, mod_wsgi, or fastCGI, you won't be able to do it directly.
I'm thinking what you might have to do is run the django app as standalone, listening on another port, then basically use PHP to proxy requests to it.
So you do your
python manage.py runserver 9999
maybe starting it with a nohup instead to keep it running when you logout:
nohup python manage.py runserver 9999 &
Then, in ~username, you make a proxy.php script that takes any additional PATH_INFO and makes a request to localhost:9999, passing along HTTP headers, collects the response, and sends it back to the browser.
So, eg, the browser requests http://example.com/~username/proxy.php/some/path/ and the PHP script requests http://localhost:9999/some/path/ and sends along the results.
I'm not a PHP programmer so I can't exactly show you how to write that, but I'm sure someone out there must have implemented an HTTP proxy in PHP.
If you have .htaccess support in that directory and apache has mod_proxy_http enabled, you could just have apache directly proxy the request. The documentation is pretty easy to follow. But if they don't have CGI enabled, they probably don't have that set up either.
Of course, the easiest thing would be if you could just get away with django running and listening on a public facing port and access it directly. Ie,
python manage.py runserver example.com:9999
and access it directly as http://example.com:9999/

Categories