Using the secondary IP in a bash script

1

I have a Primary IP set for all the system related tasks. Sometimes I have to use my system to carry out different tests and most of the time I have to deal with bash/shell scripts. I want the tests/bandwidth used to be completely apart from the Primary IP so I want to carry out the operations using the Secondary IP. How can I achieve this?

Asad Moeen

Posted 2013-10-14T17:32:11.147

Reputation: 357

That depends on the commands your script is invoking. – Der Hochstapler – 2013-10-14T17:43:09.753

It doesn't actually use any commands as one of the script is network related and keeps track of data, scans a list of servers off a master IP and updates data. Pure programming I can say. I have tried using "bind-address" commands which you might be referring to but they are command related, true. – Asad Moeen – 2013-10-14T17:45:40.140

Answers

2

This is not much about bash and not even so much about the commands you use in the script. Typically, the source IP is chosen according to the target IP. Some tools may let you specify the source IP or you can possibly rewrite the source IP using iptables if you can match the script e.g. by uid/gid.

AFAIK there's no way to attach a source IP addresses to a processes (and you would need also the subprocesses to inherit it). If you are ok with the source IP rewriting, you can switch the script process to a special group id:

As root:

ip4_address=... # fill in your ipv4 address
group=secondaryip # or any other name

groupadd $group
usermod your-user -aG $group # not needed for the root user

iptables -t nat -A POSTROUTING \
    -m owner --gid-owner $group \
    -j SNAT --to-source $ip4_address

Run the script using:

sg secondaryip "/path/to/your/script arg1 arg2"

Alternatively you can invoke individual commands inside your scripts using sg. Read its manual page for more details. Additionally there are tricks to make your script run itself with sg command but you shouldn't need that much. You can use the classic newgrp command and pass it a shell script via stdin but that won't work for perl (mentioned by your comment).

Note: The commands used in the script won't know about the modified source IP but that shouldn't generally be a problem.

For the sake of completeness, there's yet another way. You could use the LD_PRELOAD environment variable to replace some libc symbols, e.g. connect() with your own version that would perform additional actions such as binding to a specific source address. But it's a bit advanced C programming and you'd better stick with conventional waepons :).

Pavel Šimerda

Posted 2013-10-14T17:32:11.147

Reputation: 712

And how may we change the source IP based on that just for a specific script? – Asad Moeen – 2013-10-15T07:49:14.277

@AsadMoeen Let me know if the new information in the answer works for you. I'll update it if there's any problem. – Pavel Šimerda – 2013-10-15T08:05:08.213

By the way, the script does not respond when the first two lines are this: "newgrp secondaryip #!/usr/bin/perl" – Asad Moeen – 2013-10-16T15:08:07.483

True enough, see updated answer. – Pavel Šimerda – 2013-10-16T17:50:10.973

Thank you. But the "sg" command does not allow parameters to be passed to the script. – Asad Moeen – 2013-10-17T10:55:35.600

@AsadMoeen Edited. But you can still have problems with escaping the arguments. Or you can just newgrp and then run the script from the new shell that it starts. – Pavel Šimerda – 2013-10-17T14:06:06.237

Works perfectly. Thanks a million for your time. – Asad Moeen – 2013-10-17T14:44:52.597

No problem, it was a nice lesson for me as well. – Pavel Šimerda – 2013-10-17T14:54:48.977