Creating new Apache config file from PHP - php

my fellow programmers
I do have a question about Apache2 and PHP.
Well, right now I'm trying to make a script that will create new "virtual hosts" from the PHP script, without using sudo command inside PHP.
The solutions with echo passwd | /usr/bin/sudo -S command are not really secure, and I won't use something like that.
Also, I've found the solution with a www-data ALL=(ALL) NOPASSWD: is as well not a solution.
Can someone please shed some light, which is the best solution for that, and what are the best protection measures? In case I need to use a sudo inside a PHP.
Of course, that script will have some part a making a new directory, cp-ing new site files inside a dir, etc...

This sounds like a incredible bad plan security wise. You have to edit apache config files and then reload or restart the apache2 server.
You could do it by editing the sudoers file to give the www-data user the right to reload apache and add a vhost configuration to apache that the www-data user has writing rights on.
Second option is to fake vhosts via php:
<?php
switch ($_SERVER['SERVER_NAME']) {
case "site1.example.com" :
require_once 'some_config_for_site_1.php';
// load scripts from site1 folder.
break;
case "site2.example.com" :
require_once 'some_config_for_site_2.php';
// load scripts from site1 folder.
break;
default:
http_response_code(404);
break;
}

Ok, this is a really bad plan for this, but somehow this is the best solution for this.
To do this in a proper way, I'll use the bash script, and I'll call that script from PHP.
$output = shell_exec("sudo /path/to/script/script.sh $SiteName $Domain");
script.sh
#! /bin/bash
#First parameter given by calling the script
sitename=$1
#Second parameter given by calling the script
domain=$2
#Directorium where are stored files of the web app
dirlocation="/var/www/$sitename"
#Creating a new directorium
mkdir $dirlocation
#Copying the defoult files of app to the just created dir
cp -R /var/www/someapp/* $dirlocation
#Creating the new configurationg file for Apache and VHost
vhost_script="/etc/apache2/sites-available/$sitename.conf"
cat > "${vhost_script}" << EOF
<VirtualHost *:80>
ServerName $domain
DocumentRoot $dirlocation
<Directory $dirlocation>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
EOF
#Enabling the site in Apache
a2ensite $sitename.conf
#Reloading the Apache
systemctl reload apache2.service
Also in order to do this from a PHP, I need to give www-data permission for running only that script with sudo.
To do so open the sudoers file (sudo visudo /etc/sudoers) and add the following line
www-data ALL=(root) NOPASSWD: /path/to/script/script.sh
I know this is maybe not the best solution, but this is what I've found for this purpose.
Disclaimer: This is only a showcase of how to do this, also the bash script here is a really simple one.

Related

Running Shell commands and scripts from PHP - is there a correct and secure way?

I developed and operate a bespoke E-Commerce platform for a variety of customers. I want to automate some of the setup tasks, such as creating apache site config files, and installing SSL Certificates.
I have written some batch files which do both of those nicely, and I want to execute them as part of the PHP Site creation process.
I have been able to run one of these scripts using the shell_exec command in PHP, but I am confused about the permissions and concerned about security. This is all hosted on Centos Linux, and Apache web server by the way.
My batch script (create_site_config.sh) effectively generates an Apache config file for a given site and copies it to /etc/httpd/conf.d/ as 'domain.com.conf'.
The problem is, is that PHP generates this file under the ownership of apache:apache, whereas all the rest of the files in this folder are owned by root:root.
In my batch script if I use SUDO before my commands, nothing happens. Whereas if I omit SUDO, the scripts runs and creates the file for me, but under the wrong ownership. I am not able to change the ownership either.
So my PHP is something like this:
shell_exec('./create_site_config.sh);
And my batch file is something like this:
DOMAIN=$1
SYSNAME=$2
if [ -z "$1" ]
then
echo "You must pass a fully qualified domain as the first argument, ie. acme.dev.domain.com"
exit 1
fi
if [ -z "$2" ]
then
echo "You must pass a sysname as the second argument, ie acme"
exit 1
fi
#THESE COMMANDS CLEARLY RUN AS APACHE:APACHE. IF I PUT
#SUDO IN FRONT OF THEM, THEY DON't WORK AT ALL - WHAT GIVES?
rm -f ${DOMAIN}.conf
touch ${DOMAIN}.conf
chmod 777 ${DOMAIN}.conf
#START OF FILE CONTENT
cat >> ${DOMAIN}.conf <<EOL
<VirtualHost *:443>
DocumentRoot /var/www/html/siteroot
ServerName ${DOMAIN}
SSLEngine on
SSLProtocol All -SSLv2 -SSLv3
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
<Directory "/var/www/html/portals.dev">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
SSLCertificateFile /home/centos/.ssh/live_keys/${SYSNAME}_cert.pem
SSLCertificateKeyFile /home/centos/.ssh/live_keys/${SYSNAME}_key.pem
SSLCertificateChainFile /home/centos/.ssh/live_keys/${SYSNAME}_fullchain.pem
</VirtualHost>
<VirtualHost *:80>
ServerName ${DOMAIN}
Redirect 301 / https://${DOMAIN}
</VirtualHost>
EOL
#END OF FILE CONTENT
#CLEAN UP
cp ${DOMAIN}.conf /etc/httpd/conf.d/sites/${DOMAIN}.conf
#THIS COMMAND BELOW DOESN'T WORK...
sudo chmod 644 /etc/httpd/conf.d/sites/${DOMAIN}.conf
#NEITHER DOES THIS ONE...
chown root:root /etc/httpd/conf.d/sites/${DOMAIN}.conf
rm -f ${DOMAIN}.conf
sudo systemctl reload httpd.service
echo "success"
What is the correct way to do this in a away that will ensure that the files are created and that I can set the permissons of them.
Despite the above working I sense that it is not secure to do things this way. I don't understand why SUDO doesn't work in the batch script?
Clearly systems like Plesk and Cpanel are able to generate all kinds of system files and folders - what sort of techniques do they use?
I'd be grateful for any pointers.
Regards
James

localhost/~username is not working, gives 404 Not Found error

I am fairly new to server-side web development and am trying to get a local server up and running. I'm using an apache 2 server on my mac, but can't for the life of me get localhost to give me anything but 404 Not Found error. I'm putting localhost/~ and my username in the search bar and still nothing. I've been following a lynda.com tutorial to configure my personal site folder and haven't had any luck.
I'm trying to configure a personal site folder, or at least that is the terminology used in the tutorial. I created a "Sites" folder in my home directory. Then, I put an "index.html" file in the "Sites" folder to test.
After that, I configured a "httpd.conf" file through my terminal by entering "sudo nano/etc/apache2/httpd.conf". He had me un-comment the following lines:
LoadModule userdir_module libexec/apache2/mod_userdir.so
Include /private/etc/apache2/extra/httpd-userdir.conf
After doing this, I exited the file and saved the changes. I then entered into the terminal:
sudo nano /etc/apache2/extra/httpd-userdir.conf
Here I uncommented the following line:
Include /private/etc/apache2/users/*.conf
I then entered into the terminal
cd /etc/apache2/
And then:
cd users
I entered:
sudo nano jacobbryant.conf
In this file, I made sure it only contained:
<Directory "/Users/jacobbryant/Sites/">
Options Indexes MultiViews
AllowOverride None
Require all granted
</Directory>
I then exited this file and restarted the apache server with:
sudo apachectl restart
After this, I went to my browser and typed in "localhost/~jacobbryant" and got a "404 Not Found" error.
I am not sure what #jhilgeman is talking about. Apache has an extension for Per-user web directories that must be setup in order to map ~username to the home directory specified in the configuration. It looks like you have enabled the correct extension but missed the UserDir directive.
For Example: UserDir public_html will serve /home/myuser/public_html at http://your.host.tld/~myuser/
For you example, ditch the <Directory> and use the UserDir directive instead. Please read over https://httpd.apache.org/docs/2.4/howto/public_html.html for setup instructions.

Editing sudoers file not taking effect

Hey fellow programmers,
I'm working on my bachelor's project and got into a bit of a problem.
The goal is to create a web app, that can operate and modify I/O of a WAGO PLC 750-8202 (you can imagine it as some kind of industrial Raspberry PI) running an embedded linux with a lighttpd web server. I've made some C scripts that utilize DAL(HAL) functions the PLC provides.
Now I want to link it with my web application/site. I have a simple PHP page (ignore the button, it does nothing):
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<button value="CLICK ME">CLICK ME</button>
<?php
echo system("kbusdemo1");
?>
</body>
</html>
The kbusdemo1 executes but doesn't use the functions provided by DAL properly, it gives me an error. If I run that script as a root, it works perfectly. I found out that the problem lies with www user rights (that my web server lighttpd uses), so I tried editing sudoers with
sudo nano /etc/sudoers
Visudo is not implemented in the PLC linux system so I had to open it directly. I changed it to the code posted below, but if I try to run the C script as lighttpd user (with su www), it still doesn't work. What am I doing wrong?
Thanks for you suggestions.
# sudoers file.
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the sudoers man page for the details on how to write a sudoers file.
#
# Host alias specification
# User alias specification
# Cmnd alias specification
# Defaults specification
# Runas alias specification
# User privilege specification
root ALL=(ALL) SETENV: ALL
admin ALL=NOPASSWD: /etc/config-tools/get_user_info user
ALL=NOPASSWD: /etc/config-tools/get_user_info
www ALL=(ALL) NOPASSWD:ALL
# Uncomment to allow people in group wheel to run all commands
# and set environment variables.
# %wheel ALL=(ALL) SETENV: ALL
# Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: SETENV: ALL
# Samples
# %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users localhost=/sbin/shutdown -h now
Thank you for all your help. I got it working, I wasn't calling the script as sudo from the PHP file. And as you suggested, I changed the lines in sudoers to only allow that one particular script, so no security holes for me.

PHP errors written to wrong log

My Linux server is running PHP 7 as a CGI on Apache2. In php.ini I have
error_log = /var/log/apache2/php.log
Now, I have two problems:
1) All PHP errors go to /var/log/apache2/error.log instead of php.log. I have edited the right php.ini because ini_get('error_log') returns the full path of php.log in PHP.
2) When I try to open either of those files in PHP, I get permission denied. I have chmod'd both files to 777, but PHP is still unable to access them.
The server has been restarted multiple times so the configuration changes apply. My Apache configuration is this:
ErrorLog ${APACHE_LOG_DIR}/error.log
ScriptAlias /local-bin /usr/bin
AddHandler application/x-httpd-php7 php
Action application/x-httpd-php7 /local-bin/php-cgi7.0
<Directory "/usr/bin">
Require all granted
AllowOverride All
</Directory>
How can I redirect PHP errors to the right file, and also make it readable for PHP? Thanks in advance!
You need to change the owner and the group of the log directory and the log file/s (if already exist/s) to www-data:
sudo chown -R www-data:www-data /path/to/log/directory
Dont change the directory permissions to 777 as it might cause security issues, use 775 instead. For the log files use 664.
You might also want to add your system user to the group www-data if not already a member (use groups command to check for your existing groups), a system reboot is required after that for the changes to take effect:
sudo adduser user www-data #change 'user' to your

Apache and vsftp file permission

I have setup apache according to this article
https://help.ubuntu.com/community/ApacheMySQLPHP
and I have created a new site config in /etc/apache2/sites-available/mysite
and changed the document root and directory to :
DocumentRoot /home/gapton/public_html
<Dictory />
..
..
</Directory>
<Directory /home/gapton/public_html/>
...
...
...
...
</Directory>
and I sudo a2dissite default && sudo a2ensite mysite to disable and enable them, restarted apache2 and things are working.
I then setup vsftpd and config the vsftpd.conf file to :
local_enable=YES
write_enable=YES
connect via Notepad++ with the user 'gapton' and I created a file called test.php under home/gapton/public_html. It would not be readable by Apache it seems. I did sudo chmod -R 755 ~/public_html and it would load alright.
However any subsequent files created via vsftpd will not be readable.
Since I have logged in to the only account gapton when connecting via FTP, then any newly created file should be owned by gapton right? What happens when apache tries to access a file/folder location, what credentials does it access it by?
How do I config it so that all files created by gapton can be read by apache? (Also, is it at all advisable?)
Thanks.
I found the problem.
In older version of vsftpd, the umask they apply when writing file was by default 022.
In the current version, such default value has been changed to 077. This mask read 4 write 2 and execute 1 for everyone except the owner.
Changing the umask value in the vsftpd.conf file back to 022 has solved my problem. Hope this help future users of vsftpd facing the same issue.

Categories