Run a command on a SSH screen through SSH with phpseclib - php

I have a PHP script that starts a detached screen through SSH:
$ssh->exec("screen -m -d -S ".$user);
I now need to execute a command in that screen without being in that screen. I have the code that does that, which I have tested through a SSH client, but when I try to use it with the phpseclib exec command, it does not work. This is the code that works:
screen -S ".$user." -X stuff "cd minecraft/servers/".$user."/;sh start.sh $(printf '\r')"
And this is it in the PHP script:
$ssh->exec("screen -S ".$user." -X stuff \"cd minecraft/servers/".$user."/;sh start.sh $(printf '\r')\"");
I attempted to escape the extra double quotes in the code.
Is there anything I can do to make this work through PHP? Thanks

Hmmm...
create please two bash script, first: create screen with user parameter with name f.e. run_screen, second: tester for SSH client with user parameter with name f.e. run_test.
Run first script:
$ssh->exec('[full_path]/run_screen ' . $user);
and second:
$ssh->exec('[full_path]/run_test ' . $user);
bash syntax is here bash syntax
Sure that the user of server (f.e. Apache) has permissions to run scripts.

Related

Incorrect Webpage Output for PHP exec running bash script for audtool (part of Audacious)

On a local linux server (Rapsberry Pi debian stretch with desktop), I am working on sending "audtool" commands to a running Audacious media player using php, exec and bash scripts. Audacious is autostarted when the server starts up with user "pi". I have apache2 and php set up and working on the server, and I can ssh to the server and run all the commands from the cli. I believe I have resolved the issues with running audtool (dbus and setting the right environment variables) and running the php on the command line works successfully. However when running the php on a webpage I get back a long string of information about apache2
I have spent several hours (getting on for a whole day) researching this on the web in order to get to this stage, so close I can almost touch it, but stuck on this last element. The example is to display the current song from a running instance of Audacious. Audtool requires a running dbus (looks for a display). Using exec or shell_exec I have no problems running bash commands such as whoami or ls.
The php page (cursong.php):
<?php
echo exec('/var/www/html/cursong.sh');
?>
The bash script (cursong.sh):
#!/bin/bash
##call current song
pid=`pidof audacious`
user=`ps -p $pid -o user=`
export `strings /proc/$pid/environ | grep DBUS_SESSION_BUS_ADDRESS`
sudo -E -su $user /usr/bin/audtool --current-song
(from here: https://redmine.audacious-media-player.org/boards/1/topics/1058?r=1059)
Output from command line:
php -f cursong.php
Artist - Song Title (for example - so this works)
Output on webpage:
declare -x APACHE_LOCK_DIR="/var/lock/apache2" declare -x
APACHE_LOG_DIR="/var/log/apache2" declare -x
APACHE_PID_FILE="/var/run/apache2/apache2.pid" declare -x
APACHE_RUN_DIR="/var/run/apache2" declare -x APACHE_RUN_GROUP="www-
data" declare -x APACHE_RUN_USER="www-data" declare -x
INVOCATION_ID="4ce76136ca8842bd9108d6b1b9a5b9ed" declare -x
JOURNAL_STREAM="8:23896" declare -x LANG="C" declare -x OLDPWD
declare -x
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/var/www/html" declare -x SHLVL="1"
I have set www-data, the apache2 user with the following in
/etc/sudoers:
www-data ALL=NOPASSWD: ALL
and /var/www/html is rwx for anyone
Obviously, I am expecting to see "Artist - Song Title" on the webpage, but instead I get back all the apache2 info. What am i missing, or where have I gone wrong?
I hate answering my own question, makes it look like I wasn't trying hard enough! After a further five hours or so of searching around and attempting fixes, I happened upon this post on SO:
Running command-line application from PHP as specific user
which suggested putting a "sudo -u user" in the exec of the php file. I tried this with the "pi" user and it still didn't work, then I simply tried it with "sudo" and hey presto!!
The php file now looks like this:
<?php
echo shell_exec('sudo /var/www/html/cursong.sh 2>&1');
?>
Now to do some testing on how it works with the other audtool commands that don't ask for a response but require action from audacious, and to see how I can reduce scripting php files by passing a parameter to the bash script!
Just for completeness, the php and bash scripts for both a request and an action, using a parameter fed to the php url and then on to the bash script:
PHP File with Parameter
<?php
$request = $_GET["request"];
echo shell_exec("sudo /var/www/html/cursong.sh \"${request}\" 2>&1");
?>
url example:
http://192.168.1.92/cursong.php?request="--playlist-shuffle-status"
Bash Script with parameter
#!/bin/bash
##call request
pid=`pidof audacious`
user=`ps -p $pid -o user=`
export `strings /proc/$pid/environ | grep DBUS_SESSION_BUS_ADDRESS`
sudo -E -su $user /usr/bin/audtool $1
PHP file for an action
<?php
$action = $_GET["action"];
shell_exec('sudo /var/www/html/playsong.sh \"${request}\" ');
?>
url example:
http://192.168.1.92/cursong.php?action="--playback-play"
Bash script for an action
#!/bin/bash
##call action
pid=`pidof audacious`
user=`ps -p $pid -o user=`
export `strings /proc/$pid/environ | grep DBUS_SESSION_BUS_ADDRESS`
sudo -E -su $user /usr/bin/audtool $1

Passing a variable from PHP to ubuntu

I want to run a script on my ubuntu server with a variable from php in it.
Here are some of the things i've tried to pass a variable to ubuntu...
shell_exec('vpsName=HI3');
vpsName=`mysql -D jake_db -h 127.0.0.1 -u jake -pXXXXXXX -se "SELECT vpsName FROM reinstalls WHERE status = 'pending'"`;
The final way in which i thought I could fix it was to avoid running the script through ubuntu all together and run it from shell_exec(); but it fails on running the guestfish commands.
Here is my entire reinstalls.sh script.
sudo rm /var/lib/libvirt/images/"$vpsName".qcow2 && sudo wget -O /var/lib/libvi$
guestfish -a /var/lib/libvirt/images/"$vpsName".qcow2 <<'EOF'
run
mount /dev/ubuntu-vg/root /
rm /etc/network/interfaces
EOF
sudo fusermount -u /mnt && virsh start "$vpsName" && echo "IT WORKED!"
I am open to any way of getting this to work, as long as its secure,
Thanks in advance,
Jake
EDIT:
If I run the script with a VPS name instead of a variable, it works. I just can't find a way to pass the variables from the website to the ubuntu16.04 OS.
Well one way would be to run each command from PHP:
shell_exec("sudo rm /var/lib/libvirt/images/" . $vpsName . ".qcow2");
shell_exec("sudo wget -O /var/lib/libvi ... etc");
The other would be to invoke your shell script from PHP, passing the vps name as a parameter:
shell_exec("reinstalls.sh " . $vpsName)
But then you'd have to rewrite the shell script to pick up the command line parameter and apply it as necessary. In the case of bash, this explains how to go about that.

PHP Bash Script calling another Bash script

I have a bash script that takes a parameter is called in PHP by shell_exec(script.sh parameter). Basically, my goal is to call a script that is owned by another user that is not apache.
The script.sh script is a file that contains the following (right now there are some error handling commands):
#/bin/bash
whoami>>whoami
echo $1 >> parameter
while read f; do
env>>envoutput
sudo -i -u archivescriptowner /path/to/archivescript.sh -command archive >> output
done < $1
In my /etc/sudoers file , I have the following:
apache ALL=(archivescriptowner) NOPASSWD: /bin/bash -c /path/to/archivescript.sh *
When I run this script as by running su -s /bin/bash apache and pass a parameter, it works.
When I run it via my button in php, archivescript.sh does not execute
The whoami file has apache written to it
The parameter file has the right file written to it
env shows the following
Term=xterm
LD_LIBRARY_PATH=/path/to/library
PATH=/sbin/:usr/sbin:/bin:/usr/bin
PWD=/var/www/html
LANG=C
SHLVL=4
=/bin/env
PWD is outputting right, that is where my script is right now, it will be moved in the future.
The output file when it is ran by the button click is blank.
I am at a loss as to why this is not working. Any insight would be helpful. Please let me know if I need to give any additional information.
I recently published a project that allows PHP to obtain and interact with a real Bash shell. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('/path/to/archivescript.sh');
echo $return1; //return from your script

launching php script running on server (and opening sockets) from a php page

I'd need you precious help on a matter I am spending hours on.
Scope: Apache2 and PHP running on a raspberry pi;
Premise: my little knowledge of Linux environment!
The objective: launching a long-run php script, that opens sockets, from another php script running as webpage. In other terms, the application is a chat and I need to start the php server script form a web page, for my convenience.
The issue: if I run it from the the console, logged as "pi", with the following command
php -q /var/www/chatSocket.php > /var/www/tmp/socketProcessOutput.txt 2>&1 & echo $!
it works like a charm, but if it try to do so from a script, with the following (don't mind the concatenated strings and assignment of output to variables - it made no difference removing them):
$result .= "Result of pkill (killed process): " .shell_exec('sudo pkill -f SongWebSocket.php') ."\n";
$result .= "Launching new process: id returned:". shell_exec('php -q /var/www/chatSocket.php > /var/www/tmp/socketProcessOutput.txt 2>&1 & echo $!') ."\n";
$result .= "Checking running SongWebSocket.php process:" ."\n";
$result .= shell_exec('ps -A aux| grep -e SongWebSocket.php -e USER') ."\n";
.. it does not work (it seems like it launch the script but the sockets ar not open).
Any clue why this happens?
Also, and this can be for my little knowledge of Linux, why i get a dioffrent aoutput from the command
ps aux| grep -e SongWebSocket.php -e USER
if I launch it from the shell, as user pi, or from the sript, as www-data user.
I Look forward for your help. Thanks in advance!
Marco.
www-data user doesn't have the permisson I guess. why not add "sudo" for every shell_exec line? (sudo starts the programm with root permission). it's not pretty and not secure but it might work on you local home-network. sudo php ... sudo ps -A aux etc. In addition you should make sure that the php safe_mode is off. you can see that by adding phpinfo(); to you php code

Screen -X isn't working ("No screen found")

I have this php code:
echo shell_exec('sh /backups/turnon.sh');
The /backups/turnon.sh code is:
screen -X 'cd /ftb; java -Xms2048m -Xmx2048m -jar mcpc.jar'
However, that outputs to the website:
No screen session found.
However if I open PuTTY and I do screen -x I can load the screen with no issue. What am I doing wrong.
Not sure why one would do this, but as a sample of one way to do it.
www-data
One way to solve this case would be to attach to correct user session. For Apache that is normally www-data which is a user with stripped down privileges. Use ps on apache or,
in PHP you can run this to show you which user PHP (Apache) run as:
<?php echo exec('whoami'); ?>
Output:
www-data
Note that if you run the script using PHP from command-line you will get current user, which you do not want.
Initiate screen session for www-data
www-data is normally not set up with password, as such we cannot log in with that user. To run a screen session for www-data one can do the following:
$ sudo su - www-data
$ script /dev/null
$ screen
Or as a one-liner:
sudo su - www-data -c 'script -c screen /dev/null'
This will start a new shell in www-data's home directory, typically /var/www/. The script command is one way to prevent access error to terminal when running screen due to the use of sudo su.
Execute script from PHP
Now that we have a screen session for www-data we can continue with the Bash script.
/usr/bin/screen -X stuff '/usr/bin/java -cp /some/path/ Test
'
and execute it from PHP.
Capturing output
If you want the buffer from screen in PHP there is various ways:
First create a log-file for www-data's screen session.
touch /tmp/www-data-scr.log
chown www-data:www-data /tmp/www-data-scr.log
Use logfile option in .screenrc and run screen with -L.
Run script -f /tmp/www-data-scr.log inside screen.
Start www-data script screen session with log-file, -f to flush.
sudo su - www-data -c 'script -fc screen /tmp/www-data-scr.log'
Copy buffer to file to get a snapshot.
/usr/bin/screen -X hardcopy /tmp/www-data-scr.log
etc.
You would typically add a
sleep N
in your bash script after issuing the command producing some output and before reading the log file.
To sum up
As privileged user:
touch /tmp/screen.log
sudo chown www-data:www-data /tmp/screen.log
sudo su - www-data -c 'script -c screen /dev/null'
Bash script:
#!/bin/bash
/usr/bin/screen -X stuff 'java -cp /some/class/path/ Test
'
sleep 1
/usr/bin/screen -X hardcopy /tmp/screen.log
sed '/^$/d' /tmp/screen.log
PHP:
<pre>
<?php
echo "-----------------------------------------------------------\n";
echo htmlentities(shell_exec('sh /path/to/script'));
echo "-----------------------------------------------------------\n";
?>
</pre>
The man page for screen specifically states:
-x Attach to a not detached screen session. (Multi display mode).
-X Send the specified command to a running screen session.
The error message you're getting says that there's no existing screen process running to attach to. Something is different between your PuTTY login environment and the environment in which the script is trying to run, possibly that you have a screen session running as your PuTTY login user but none running as the user running the script.

Categories