Report this

What is the reason for this report?

run a script.sh from php / apache where sftp perform connection and upload

Posted on June 17, 2018

Hi All, assume that I have a script.sh that runs perfectly if launched from a root shell.

#!/usr/bin/sh
sftp -oPort=22 user@localhost<<EOF
put /var/www/html/xml/file.xml /var/www/html/destination/file.xml
exit
EOF

what I need is to run this script from php / apache, I’ve just try a lot and what give me the possibility to see something of what happen is a code like that :

$cmd = '/bin/sh /var/www/html/script.sh';

    if(exec("$cmd  2>&1", $output, $return_var)) {
    print_r($output);
    $upl.= "<br>";
    print_r($return_var);

I receive that : Array ( [0] => Could not create directory ‘/usr/share/httpd/.ssh’. [1] => Host key verification failed. [2] => Couldn’t read packet: Connection reset by peer ) 255

note the my key is just accept from the destination server because I can run the script in shell by root and I’m not sure to make something bad making the .ssh dir onto /usr/share/httpd/ where the sys after can make the know_hosts because in all the case in local continue to not work.

I think this is not the exact approach in CentOS suggestions ? always thanks Gio



This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Hello,

On Centos the default user that Apache is running with is called httpd that is why when you run the shell script through Apache it tries to create the /usr/share/httpd/.ssh folder.

A quick fix would be to generate a new ssh key and add it in the /usr/share/httpd/.ssh directory, then the Apache user would have access to the key that it needs to authenticate with against the destination server.

Though on another note, I would recommend figuring out a different way to do this as running shell commands with your Apache user is not exactly secure. You could for example create a cronjob and run this command at a specific time.

Regards, Bobby

The issue you’re encountering stems from the fact that Apache is running as a different user (typically apache or www-data), and this user does not have the necessary SSH configuration set up, which is why you’re seeing errors like “Could not create directory /usr/share/httpd/.ssh” and “Host key verification failed.”

Here’s how you can resolve the issue:

1. Set Up SSH Keys for the Apache User

Since Apache is trying to run the SFTP command, the user running Apache (likely apache or www-data) needs to have an SSH key set up and authorized on the remote server.

a. Find Out Which User Apache is Running As

Check which user Apache is running under:

ps aux | grep apache  # or httpd on CentOS

It’s likely apache, but if not, adjust the following commands to the appropriate user.

b. Switch to the Apache User

You’ll need to set up SSH keys for this user. Switch to the apache user:

sudo su -s /bin/bash apache

c. Generate SSH Keys for the Apache User

Generate an SSH key for the Apache user (if not already present):

ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa

d. Copy the Public Key to the SFTP Server

Copy the public key to the remote server (localhost in this case):

ssh-copy-id -i ~/.ssh/id_rsa.pub user@localhost

This ensures that the Apache user can connect to the SFTP server without requiring a password.

e. Test the Connection

Test that the Apache user can connect via SSH:

ssh user@localhost

If the connection is successful and doesn’t ask for a password, the keys are set up correctly.

2. Avoid Using the /usr/share/httpd/.ssh Directory

The error indicates that Apache is attempting to create the .ssh directory in /usr/share/httpd/. This can happen if the home directory is not correctly set for the Apache user.

To fix this:

  • Ensure that the .ssh directory is located in /var/www/ or another location where Apache has the proper permissions.

For example, the SSH configuration for Apache should be in /var/www/.ssh/ or /home/apache/.ssh/ if the user’s home directory is set properly.

3. Grant Apache Access to the SSH Key

Ensure that the Apache user has access to the .ssh directory and the SSH key files:

sudo chown -R apache:apache /var/www/.ssh
sudo chmod 700 /var/www/.ssh
sudo chmod 600 /var/www/.ssh/id_rsa

4. Modify the Script for Apache Compatibility

In your PHP script, you can use sudo to ensure that the script is executed with the right permissions. First, allow the Apache user to execute the script without a password by editing the sudoers file:

sudo visudo

Add the following line to allow apache to run /var/www/html/script.sh without a password:

apache ALL=(ALL) NOPASSWD: /var/www/html/script.sh

5. Update Your PHP Code

Finally, update your PHP code to execute the script using sudo:

$cmd = 'sudo /bin/sh /var/www/html/script.sh';

exec("$cmd 2>&1", $output, $return_var);

print_r($output);
print_r($return_var);

. Check SELinux (if applicable)

If you’re running SELinux, it might block Apache from accessing certain files or executing commands. You can either temporarily disable SELinux for testing or adjust its policy to allow Apache to run the script.

Disable SELinux temporarily:

sudo setenforce 0

If this resolves the issue, you’ll need to adjust SELinux policies to allow Apache to run the script permanently.

Summary

  • Set up SSH keys for the Apache user to ensure passwordless SFTP access.
  • Ensure the .ssh directory and key files are in the correct location and have the right permissions.
  • Update your PHP script to run the shell script using sudo without requiring a password.
  • Check SELinux if applicable.

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.