Php execute ssh git pull script without sudo (host verification error) - php

What I am trying to do
I have a git repository on bitbucket. After pushing to the repository from my local machine I want to automatically pull the master branch to my webspace.
What I have done so far
I connected to my server using ssh, created the ssh key and registered the public key on github.
I created a .sh script which pulls the master branch using ssh - so far so god - everything works when I run the script from the command line/putty
What is the problem
I want to trigger the .sh script with a webhook on bitbucket (I can give an url). For that purpose I created a .php file in my webspace:
<?php
$output = shell_exec('./deploy.sh 2>&1');
echo $output;
my .sh script looks like this:
#!/bin/bash
git pull git#bitbucket.org:dualmeta/test.git master
As already said, running the .sh script with putty works perfectly fine. However if I enter the url to the .php file in my browser it gives me an error:
Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
I already did some reserach and found that many people have the exact same problem. However in my case i do not have root/sudo access because it is a rented webspace and not my own vServer.
Is there any chance getting this to work?

You must add access www-data or apache user to your git directory.
chown -R apache:apache git_directory
or
chown -R www-data:www-data git_directory
or
chmod o+rw -R git_directory
Use this too :
git config credential.helper store

Related

ERROR: Repository not found whilst running git pull via shell_exec on php script

I have set up ssh keys properly and added them to my github account . Whenever I ssh into the server and run git pull , everything runs normally and it pulls changes from the repository . However I have a deploy script that runs git pull via shell_exec() but it returns this error;
origin git#github.com:sayopaul/autodeploy-tutorial.git (fetch)
origin git#github.com:sayopaul/autodeploy-tutorial.git (push)
ERROR: Repository not found.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
PHP (the webserver) likely doesn't run as the same user you use when you SSH into the server. Thus, it doesn't have access/permission / doesn't use the correct SSH keys to authenticate vs GitHub.
I can think of 2 easy solutions:
Utilize sudo:
Add this rule in the sudo-conf (sudo visudo) to allow the user www-data to run (only) /usr/bin/git as yourotheruser:
www-data ALL=(yourotheruser) NOPASSWD: /usr/bin/git
Now you can invoke git using:
sudo -u yourotheruser git pull
Security advise: To limit the potential damage done if someone manages to execute arbitrary code through www-data:
Create a script owned by yourotheruser (and not writeable by others), e.g. /home/yourotheruser/deploy.sh with the contents:
cd /path/to/repo
git pull
And allow the sudo access only to this script. This way, no other git action than pull in the intended directory can be performed.
Change the user PHP itself is executed with:
Use php-fpm
Use the ITK MPM

Github Pull Webhook with PHP - Apache permissions

I'm setting up my server to listen to a webhook which is currently
shell_exec('git pull 2>&1');
Receiving and executing is working fine, except the to get it to actually replace files I need to give www-data (apache debian) permission to write all the files/folders on my webserver, right?
Currently I'm getting this as a result (no write permissions)
Updating 115da6c..9e82ef0
error: unable to unlink old 'example-path/html.html' (Permission denied)
What are the security implications of giving www-data permission to write files, and is this the right choice or am I doing things all wrong?
Another ways to achieve what you want:
sudo. Configure sudo to run the command passwordless and run shell_exec('sudo git pull 2>&1');.
Create a setuid wrapper that runs git pull and run shell_exec('git_pull_suid_wrapper');.

'git pull' command work from terminal but not with php shell_exec() via git repository hook

I have create a webhook in my github repository which post on the hook url on my live server to run pull command for update my repo files on the server.
The problem is the hook file which i have created is in the /var/www/site/web/hookfile.php (the post request is going there. i am getting the body response also)
and my repo files are in /var/www/git-repo/
its not updating the git-repo when i push anything to my github repository.
I run this command using terminal and its working.
cd /var/www/git-repo && git pull
But through my php file its not working
shell_exec('cd /var/www/git-repo && git pull')
shell_exec() fail silently because only report STDOUT and not STDERR.
Try with:
echo shell_exec("cd /var/www/git-repo && /full/path/to/bin/git pull 2>&1");
Normally is a permission error, and could be fixed adding permission to the user that execute php (apache?)
chown -R www-agent:www-agent repository/
But could be also a connection error to the remote repository (authentication, ssh-keys, ...).
First of all in your php file run a test against your server instance to get any error messages output on screen because the exec() family of functions simply fail silently and only report STDOUT and not STDERR:
echo shell_exec("cd /website/root/htdocs && git checkout . && git status 2>&1");
In my case this threw an error that it could not find git command due to lack of binary path defined for apache user. Therefore, a full path needs to be provided to git's binary. It can be obtained by finding it manually or running in shell:
'which git'
It returned (further called YOU_FULL_GIT_BINARY_PATH_HERE):
/usr/local/git/bin/git
A full path with git command e.g. '/usr/local/git/bin/git status' now runs git commands nicely.
Another thing is to ensure your web server user has enough permissions to read/write to your repo folder/files. I have set mine to be owned by the apache user (Centos 6.8; other releases might be www:www or www-data:www-data etc.):
chown -R apache:apache YOUR_WEB_OR_REPO_FOLDER
In order to ensure any newly added files inherit correct permissions run:
chmod -R g+s YOUR_WEB_OR_REPO_FOLDER
The above should get your script to run commands now. Though it doesn't overcome git password prompt to use 'git pull' command for a git user set in YOUR_WEB_OR_REPO_FOLDER/.git/config file. Running below command inside repo:
git config credential.helper store
command will prompt for password and let you store it locally. Please note your stored password will be unencrypted and protected only by file system e.g. in /root/.git-credentials. This will allow to run 'git pull' without prompting for password.
It's not ideal for my fully automated continuous integration environment deploying test VPS on demand as it requires to manually enter git user (defined in repo's .git/config git) password at least once.
Since my environment should always run on code from remote's origin/master copy I am also running
/YOU_FULL_GIT_BINARY_PATH_HERE/git checkout .
before invoking 'git pull' to ensure any local changes are lost forever alternatively do a hard reset instead using:
/YOU_FULL_GIT_BINARY_PATH_HERE/git fetch origin
/YOU_FULL_GIT_BINARY_PATH_HERE/git reset --hard origin/master

Allow Apache to execute git pull

Haven't been able to figure this out yet.. I've seen a few answers around but none of them help.
I'm trying to use Github Webhooks to have github hit a url on my server and have the server pull down newly committed items as soon as that hits. I have a php script with the following:
<?php `git pull git#github.com:my-user/myrepo.git`; ?>
However that script when hit is run as user apache so I tried:
chown -R apache:apache .
and it still has a permission denied error.
So then I tried editing the sudoers file and changing the following:
Host_Alias LOCAL=127.0.0.1
apache LOCAL=NOPASSWD: /var/www/html/git-hook.php
and that still doesn't work.
How can this be accomplished? If I run:
sudo php git-hook.php
it works just fine so nothing is wrong with the code in the php file. I just want that to be automated.
Any ideas?
Edit:
I also forgot to mention. I even created a folder /home/apache/.ssh and copied the public key for the git pull over and same result.
Change your PHP to run git via sudo
<?php `sudo git pull git#github.com:my-user/myrepo.git`; ?>
Then change your suoders to allow git to be run by the apache user
apache ALL = NOPASSWD: /usr/bin/git
There are already Git Wrappers and librarys. Maybe you can try one of them:
https://github.com/kbjr/Git.php and/or http://www.gitphp.org/projects/gitphp/wiki
I did this for a dev site -- i wouldnt advise this for a prd site although i cant think of anything particularly dangerous about it provided the scripts dont take parameters..
I created a php script that does a git pull. In the web browser I navigate to that script and any changes pushed by deisgners etc are automatically deployed.
http://.../gitpullscript/gitpullscript.php
This works by creating a git checkout that the apache user owns. You do this by creating a directory somewhere outside the document root belongs to the apache user (www-data in this case). Then a git clone into that directory, so all the files belong to www-data. afterwards soft link the directories i want into my document root so they can be accessed ni the web browser.
www-data is not in the git group, and the repositories are setup so that everyone can read (but not write).. therefore www-data can pull but not push
in the project heirarchy I created a directory to hold the gitpull script.. I use .htaccess to password protect this dir.
<?php exec('cd /var/www-data/projects/myrepo; git pull');
mkdir /var/www-data
sudo chown www-data-www-data
su www-data
mkdir /var/www-data/projects
cd /var/www-data/projects
git clone my-repo

Running git pull from a php script

I was trying the Perfect Workflow, with Git, GitHub, and SSH, and i have everything set up, except running the command git pull from php.
When i run exec('git pull') i get:
Could not create directory '/.ssh'. Host key verification failed.
fatal: The remote end hung up unexpectedly
If i run it in the terminal (as root) it works just fine, but i need this hook to work from the Post-Receive URL (Github).
If i do exec('whoami') i get apache.
It's a (dv) from mediatemple with CentOS.
If you want apache (the user) to be able to pull from git, you'll have to create an ssh key for apache, then add that to the read only keys on github.
The flow is something like this (tweak to your needs)
usermod -s /bin/bash apache
su apache
cd ~
ssh-keygen # work through the keygen dance (added a dash)
Upload (tilde here refers to apache's homedir) ~/.ssh/id_rsa.pub to github and give apache access to whichever repos it needs to pull from.
Then you can test on the server by again su'ing to apache and running the git pull
su apache
cd ~/working-copy
git clone my-project
Once that's working you should be able to run a git pull through PHP.

Categories