简体   繁体   中英

sudo command inside shell script and called by PHP

Background

I have made a PHP web application to execute a Linux Shell Script to change the data in network-scripts of CentOS 7. In other words, this is a PHP web application that can change the IP in CentOS 7.

The script itself is good to change, I can run the script using SSH with proper arguments, the usage like the following:

sh ./ipchanger.sh <fileName> <oldIpAddress> <newIpAddress> <oldSubnetMask> <newSubnetMask> <oldGateway> <newGateway>

Sample usage:

 sh ./ipchanger.sh /etc/sysconfig/network-scripts/ifcfg-ens32 192.168.1.5 192.168.1.205 PREFIX0=32 PREFIX0=24 192.168.1.1 192.168.1.1

That will change the IP from 192.168.1.5 to 192.168.1.205 and the subnet mask will be changed from 255.255.255.255 to 255.255.255.0 . The gateway will remain unchanged.


PHP Application

The data will be posted from a form processed with PHP. The code will check if the IP addresses are correct or not. If the arguments are collected and correct, my PHP code will call the shell script to make changes to the network-scripts.

Like this:

$retval = exec('sh /var/www/html/ipchanger/ipchanger.sh {$fileName} {$currentIpAddress} {$newIpAddress} {$currentSubnetMask} {$newSubnetMask} {$currentGateway} {$newGateway}');

That means:

$retval = exec('sh /var/www/html/ipchanger/ipchanger.sh /etc/sysconfig/network-scripts/ifcfg-ens32 192.168.1.5 192.168.1.205 PREFIX0=32 PREFIX0=24 192.168.1.1 192.168.1.1');


Shell Scripts

#!/bin/sh
#
# My IP Changer

fileName="$1"
currentIpAddress="$2"
newIpAddress="$3"
currentSubnetMask="$4"
newSubnetMask="$5"
currentGateway="$6"
newGateway="$7"

`sudo sed -i -e "s/$currentIpAddress/$newIpAddress/g" ${fileName}`
`sudo sed -i -e "s/$currentSubnetMask}/$newSubnetMask/g" ${fileName}`
`sudo sed -i -e "s/$currentGateway/$newGateway/g" ${fileName}`


Problem

The file /etc/sysconfig/network-scripts/ifcfg-ens32 doesn't changed at all. If I run the shell script in SSH (refer to sample usage in background chapter), it works! So my shell script should be fine.


Other Trials

1. Put echo in shell script to see if the arguments are in the correct position
Result: Yes.
The arguments showed just like expected.

2. Put 2>&1 behind the exec()
Result: Message showed.
sudo: sorry, you must have a tty to run sudo . I don't know if sed needs root permission or not. So I put it in the shell script anyway to make the shell script execute smoother.

3. Remove sudo in shell script
Result: In SSH, good; In PHP, message showed.
sed: couldn't open temporary file /etc/sysconfig/network-scripts/sedJfDtCD: Permission denied . I googled this message. When using sed -i , it will create a temporary file to store the original file in case the script messed up.

4. Remove -i in sed command in shell script
Result: Failed.
The script cannot perform its task.


Other Information

  • OS: CentOS
  • Web server type: LAMP
  • whoami: apache
  • Script usage: Internal use. So I don't care about security issues
  • Please help! Thanks.

    not directly for you right problem but i advice to add some security on such file change

    and optimize the three last lines with:

    `sudo sed -i -e "s/$currentIpAddress/$newIpAddress/g;s/$currentSubnetMask}/$newSubnetMask/g;s/$currentGateway/$newGateway/g" ${fileName}`
    
    • the last g of each of your s/// is normaly not necessary (only 1 change by line)

    I recently published a project that allows PHP to obtain and interact with a real Bash shell (as user: apache/www-data or root if needed). Get it here: https://github.com/merlinthemagic/MTS

    After downloading you would simply use the following code.

    //You could maintain your ipchanger.sh script and simply trigger that script
    //through the shell, but the point of the shell project is that it lets you 
    //trigger commands directly. in your case you could do this:
    
    $ifFilePath = '/etc/sysconfig/network-scripts/ifcfg-ens32';    
    
    $ifCfg= "DEVICE=ens32";
    $ifCfg.= "\nIPADDR=192.168.1.205";
    $ifCfg.= "\nPREFIX0=24";
    $ifCfg.= "\n192.168.1.1";
    
    $strCmd = "echo \'".$ifCfg."\' > \'".$ifFilePath."\'";
    
    //But if you wanna stick with your script then:
    
    $strCmd = "sh ./ipchanger.sh /etc/sysconfig/network-scripts/ifcfg-ens32 192.168.1.5 192.168.1.205 PREFIX0=32 PREFIX0=24 192.168.1.1 192.168.1.1";
    
    //in either case the $strCmd is triggered like this:
    $shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
    $return1  = $shell->exeCmd($strCmd);
    

    After the config file change you can then reload the interface config using the same shell:

    $return2  = $shell->exeCmd('service network restart');
    

    The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM