0

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.

    AkiEru
    • 780
    • 1
    • 9
    • 34
    • Well, your problem is right there: `sudo: sorry, you must have a tty to run sudo`. `sudo` does not run when called from anything other than a tty (which is a login shell, as opposed to the PHP script you try to call it from). – Bart Friederichs Sep 04 '15 at 07:01
    • 1
      Give your script the proper permissions and you won't even need to think about doing this. – l'L'l Sep 04 '15 at 07:05
    • 1
      This question might help: http://stackoverflow.com/questions/3173201/sudo-in-php-exec especially the `requiretty` part from `visudo`. – Bart Friederichs Sep 04 '15 at 07:05
    • @l'L'l The file has chmod to 0777 in the following files: `index.php`, `ipchanger.sh`, `ifcfg-ens32` and the owner is root. – AkiEru Sep 04 '15 at 07:07
    • `chmod` is only part of it; you'll also need to modify the scripts owner `chown`. – l'L'l Sep 04 '15 at 07:17
    • Re I'L'I: The script owner is also root. The whole application is owned by root as I upload all of these files by root@SFTP. – AkiEru Sep 04 '15 at 07:18
    • @BartFriederichs Your suggestion can let PHP to use sudo now. If there is other method that won't use sudo and it will be better (like copy the file and edit it and overwrite the file). But thanks! Cheers. – AkiEru Sep 04 '15 at 07:22
    • @AkiEru you will need root access at some point. – Bart Friederichs Sep 04 '15 at 07:40
    • @BartFriederichs so you think this is already the best way to solve? It's perfectly fine to me though. So don't keep it in mind. :) – AkiEru Sep 04 '15 at 07:41
    • @AkiEru no, I think it is a Bad Idea to change IP addresses (or any root access) from a PHP script. But that's not the point I guess. – Bart Friederichs Sep 04 '15 at 07:42
    • @BartFriederichs I think I would add a command to remove apache from `/etc/sudoers`. Because this is just a one-time-use scripts. – AkiEru Sep 04 '15 at 08:05

    2 Answers2

    0

    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)
    NeronLeVelu
    • 9,908
    • 1
    • 23
    • 43
    • I am a newbie to Shell Script (started learning 3 days ago) so thanks for your suggestion. I have edited my shell script. – AkiEru Sep 04 '15 at 07:40
    0

    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');
    
    MerlinTheMagic
    • 575
    • 5
    • 16