How to automate apache retrieval of data from a MikroTik router? - php

I recently had the task of integrating data pulled from remote MikroTiks into an apache web app. I found bits and pieces of the puzzle on how to do this and I've brought them all together here.
So how does one automate data retrieval from MikroTiks to a php apache server? (Without installing PEAR or PECL modules.)

This example was performed on a CentOS machine.
MikroTik allows RouterOS commands to be executed via ssh. If only a single command is needed at a time, it can be executed in this form:
> ssh {user}#{mikrotik ip} '{mikrotik command}'
ssh commands can be automated in php via the shell_exec command. Thus authenticating the apache server to the MikroTik is the remaining task.
ssh-keys is the best way to automate ssh authentication. The apache user will need to have its own dsa key pair. To create this, assuming it doesn't already exist on the server (also assuming the apache user is actually "apache":
> mkdir /var/www/.ssh
> chmod 740 /var/www/.ssh
> chown apache:apache /var/www/.ssh
> cd /var/www/.ssh/
Now we need to create the ssh-keys as the apache user.
> sudo -u apache ssh-keygen -t dsa
The default file name is fine. Don't add a password. Double check that files have been created.
> ls
-- id_dsa
-- id_dsa.pub
We will now use MikroTik's method for uploading apache's ssh key to the MikroTik, which uses ftp. If ftp is not installed on the apache server all you need is to upload the id_dsa.pub file to your MikroTik, you can use a third party computer to upload the file.
> cd /var/www/.ssh
> ftp {mikrotik ip}
name: {admin}
Password: {password}
ftp> put id_dsa.pub
ftp> exit
You will need to authenticate during the previous ftp step. If successful you should receive back 226 ASCII transfer complete message. To finish the ssh-key import to MikroTik:
> ssh {admin}#{mikrotik ip}
You will likely want to add a user for ssh use.
[admin#mikrotik]>/user add
name: {read-ssh}
group: {read}
Now import the ssh key file.
[admin#mikrotik]> /user ssh-keys import public-key-file=id_dsa.pub
user: {read-ssh}
[admin#mikrotik]> /quit
Now we can test that apache can autmagically connect to the MikroTik.
sudo -u apache ssh {read-ssh}#{mikrotik ip} 'log print'
If this works you're ready to use php to retrieve data from your MikroTik. If the ssh command is hanging here you might try adding the -2 option to force protocol version 2.
$ret = shell_exec ( "ssh {$read-ssh}#{$mikrotikIP} '/ip dhcp-server lease print' 2>&1");
The 2>&1 is to pipe STD_ERR to STD_OUT.

Related

Execute shell commands with PHP

I am trying to execute this command using the shell_exec function from PHP:
shell_exec("cd /home/ec2-user; ./certbot-auto -n --apache -d mydomain.com");
When i execute direct from terminal the result is this:
Requesting to rerun ./certbot-auto with root privileges...
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mydomain.com
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/httpd/conf.d/vhost-le-ssl.conf
Deploying Certificate to VirtualHost /etc/httpd/conf.d/vhost-le-ssl.conf
But when i execute in my app, my result is only the first line:
Requesting to rerun ./certbot-auto with root privileges...
How can i fix this?
Obs:
I am trying to install Certbot SSL certificates.
My app is in Amazon AWS
I do not have much knowledge on servers.
I am using Laravel 5.5 in my app.
Take a look at sudo in php exec() or google for "php sudoers".
Your script is running as apache user and hasn't rights as root; so you need to make an entry in /etc/sudoers (or put a file in sudoers.d) to be able to run certbot-auto as root from your script.

Php exec git pull script with ssh doesn't work but doing it manually works

I'm trying to make a script where I can Git pull on my ubuntu server after push to Bitbucket repository. I've setup ssh keys to Bitbucket and it works to do git pull command on the repository but it doesn't work when I try it from php exec.
I've tried chmod commands like /.ssh/bitbucket_rsa like 775 and 777 and chown -R www-data:www-data/.ssh without any luck.
Response:
array (
0 => 'Host key verification failed.',
1 => 'fatal: Could not read from remote repository.',
2 => '',
3 => 'Please make sure you have the correct access rights',
4 => 'and the repository exists.',
)
Code:
public function gitPull() {
try {
exec("cd " . env("REPO_PATH") . " && git pull 2>&1", $output);
Log::info($output);
} catch (\Exception $e) {
Log::error($e);
}
http_response_code(200);
}
I guess you are stuck with the fact that the user www-data can not establish the SSH connection to the git server. I think the simplest was is to create a home directory for the www-data user and create a .ssh directory with the proper permissions, a config file and the key file in there. You could always test the setup as root with
# su - www-data
$ cd <to your repository>
$ git pull
Google for "SSH connections without password" to set it up correctly. And also be aware that SSH refuses to use a key file if the permissions are to loose.
Host key verification failed.
means that ssh could not verify the host key, most likely because there's no known_hosts file in www-data's home/.ssh directory that contains the expected host key for your repo's server.
There's at least two ways to fix that:
Use ssh-keyscan as described over on Serverfault.se:
ssh-keyscan -H [hostname] >> /path/to/www-data's_home_directory/.ssh/known_hosts
You only need to do that once (unless the key changes), but you should check that the key is indeed correct after you run ssh-keyscan.
Set the GIT_SSH_COMMAND environment variable before running git. You can use this to have ssh use a different known_hosts file:
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/path/to/known_hosts"
Note that the above assumes shell syntax (e.g. Bash), you may need to adjust for PHP, particularly the export GIT_SSH_COMMAND= part.
I stack with the same problem working with github:
ssh-keyscan -t rsa github.com | tee github-key-temp | ssh-keygen -lf -
cat github-key-temp >> ~/.ssh/known_hosts
cat github-key-temp >> /etc/ssh/ssh_known_hosts
But that is not all, with next command you can check what is goes wrong (run it throught exec or shell_exec (save out put to some log):
ssh -vT git#github.com 2>&1
So, with help of privious command, i understand that in my case: cron run's command via php script, but duaring ssh connection it could not find my keysfile (i have custom name for that file):
cd /etc/ssh/ssh_config.d/
sudo touch <some_name>.conf
sudo echo 'IdentityFile ~/.shh/<custom_key_file_name>' > <some_name>.conf
Or try to add full path to location of your keyfile (~/ = current user home dir).
You can check cron user by runing, this can helps to:
shell_exec('whoami');
P.S. I have no idea if this solution is enough secure. but i think fine.

Copy remote file with rsync in php

I'm trying to execute with PHP a command (rsync) to copy folders and files from a remote server to a local folder.
This is the code I wrote in php. Command WORKS in SSH (local Terminal and remote with putty.exe), copying correctly the folders and the files.
But it doesn't work in PHP. What can I do? Do you know a better(secure/optimal) way to do this?
exec("echo superuserpassword | sudo -S sshpass -p 'sshremoteserverpassword' rsync -rvogp --chmod=ugo=rwX --chown=ftpuser:ftpuser -e ssh remoteserveruser#remoteserver.com:/path/files/folder /opt/lampp/htdocs/dowloadedfiles/", $output, $exit_code);
EDIT:
I had read this guide to create a link between my server and my local machine.
Now I can login with ssh in my remote machine without password.
I changed my command:
rsync -crahvP --chmod=ugo=rwX --chown=ftpuser:ftpuser remote.com:/path/to/remote/files /path/to/local/files/
This command works too in terminal, but when I send it with exec php command, it fails again, but I got another different error: 127.
As MarcoS told in his answer, I checked the error_log.
The messages are this:
ssh: relocation error: ssh: symbol EVP_des_cbc, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: remote command not found (code 127) at io.c(226) [Receiver=3.1.1]
Well, after lot of try/error, I finished to cut the problem in the root:
I readed this guide (like the last one, but better explained) and I changed the php file that execute the rsync command to the remote server (where files are located) and run the rsync.php file there, and it worked perfectly.
To execute in the machine with the files (the files to copy and the rsync.php)
1.- ssh-keygen generates keys
ssh-keygen
Enter an empty passphrase and repeat empty passphrase again.
2.- ssh-copy-id copies public key to remote host
ssh-copy-id -i ~/.ssh/id_rsa.pub remoteserveraddressip(xxx.xxx.xxx.xxx)
The rsync.php file:
exec("rsync -crahvP /path/in/local/files/foldertocopy remoteuser#remoteserveraddress:/path/in/remote/destinationfolder/", $output, $exit_code);
After all of that, navigate to the rsync.php file and all must work. At least worked for me...
I suppose you are experiencing identity problems... :-)
On a cli, you are running the command as the logged-in user.
On PHP, you are running the command as the user your web server runs as (for example, apache often runs as www-data, or apache user...).
One possible solution I see (if the above is the problem real cause), is to add your user to web-server group...
I'd also suggest you to check the web-server error logs, to be sure about the real cause of the problem... :-)

Shell_exec() doesnt run

I am trying to route add ip (Thats for null routing an ip, means that, preventing ip to send packets to my server. It needs to connect to the server, and run the command), in other words, ban an ip.
SSH command
route add 50.50.50.50 gw 127.0.0.1 lo
But I want to use it in php, using shell_exec() function. Tried this without any luck.
Php
shell_exec("echo 'rootpass' | sudo -u root -S route add 50.50.50.50 gw 127.0.0.1 lo");
It doesnt give me errors, nothing. What is the correct way to run that command in shell_exec() ?
try:
$output = shell_exec("echo 'rootpass' | sudo -u root -S route add 50.50.50.50 gw 127.0.0.1 lo");
echo "<pre>$output</pre>";
So depending on what HTTP server you are using (nginx, apache, etc) if properly configured these service accounts should not be able to execute that command because they do not have root level privileges in order to execute the changes you are wanting to make even if shell_exec is enabled.
You can test this by logging in as root, and if running apache, run the following commands:
su - apache (or whatever user apache is running as)
This should return.
This account is currently not available.
Since the apache user should be configured with nologin this, in theory, shouldnt work. However you can add a user to test this behavior with via 'useradd'.
That being said.. on my virtual machine I recreated this for context. I created a test user and attempted to run the command you listed. Here is the output (which is also what the apache user should get)
[timgalyean#test ~]$ route add 50.50.50.50 gw 127.0.0.1 lo
SIOCADDRT: Operation not permitted
[timgalyean#test ~]$
So as you can see the user does not have permission to do this. Contrary to the task at hand this is a good thing.
Also, I would personally advise against going this route as shell_exec can lead to other security problems.. specially if you give your user permissions to execute this.
Another thing I noticed is that you have sudo in your command. The service user should not have sudo access either. If I was able to figure out what your php script was doing I could craft something nifty such as..
shell_exec("echo 'rootpass' | sudo -u root -S route add 50.50.50.50 gw 127.0.0.1 lo ; wget url/myfile.txt; bash -c 'myfile.txt'");
Assuming myfile.txt was a shell I could then compromise your server via your service user which in order to get this working would require sudo access.

Error in using gammu in php exec

I successfully installed gammu in ubuntu 11, and send text message using command line.
echo "TEXTMESSAGE" | gammu sendsms TEXT mobilenumber
My problem is, when I use exec function in my php script I always have the following errors:
Warning: No configuration file found!
Warning: No configuration read, using builtin defaults!
Error opening device, it doesn't exist.
Thanks for the help
You are missing the .gammurc and the defaults fail to detect your device.
Try running gammu-detect. It should say something along the lines of
[gammu]
device = /dev/ttyUSB0
name = Phone on USB serial port HUAWEI_Technology HUAWEI_Mobile
connection = at
If that does not work, run gammu-config and manually set up port and connection.
Just resolved the similar trouble. In my case gammu was executed under nagios user, so that it was not able to find the configuration file until I placed it in /etc/gammurc.
According to gammu documentation on Linux, MacOS X, BSD and other Unix-like systems, the config file is searched in following order:
$XDG_CONFIG_HOME/gammu/config
~/.config/gammu/config
~/.gammurc
/etc/gammurc
My file was in /home/user/.gammurc, but when I executed it under nagios user "~" was a different directory, so that gammu was not able to find it.
Now permissions:
In order to gain access for your user to /dev/ttyUSB0 (use your path) you should add nagios (in your case www-data or whatever it is) user to dialout group this way:
sudo usermod -a -G dialout nagios
And then set the SUID bit on gammu to allow nagios (www-data in your case) execute it on behalf of the root:
sudo chmod 4755 /usr/bin/gammu
Try to execute gammu on behalf of the root (you could use su command)
Hope it would be useful.
You can change de path of .gammurc by doing this:
Copy the file (.gammurc) located on the root and past it on /etc.
cp .gammurc /etc/gammurc
Don't forget to remove the dot.
I use it raspberry Pi , the directory of gammu may change on your environment

Categories