A vinculação de aplicativos a um endereço IP específico é um problema notoriamente difícil: nem todos os aplicativos são tão bons quanto ssh que permite especificar o endereço IP ao qual você deseja vincular por meio do -b opção. Por exemplo, o Firefox e o Chrome são notoriamente impermeáveis a isso.
Por sorte, há uma solução: esse cara modificou a biblioteca do sistema bind.so para permitir que um especifique o endereço de ligação na linha de comando, da seguinte forma:
$ BIND_ADDR="192.0.2.100" LD_PRELOAD=/usr/lib/bind.so firefox
Ao pré-carregar o objeto compartilhado bind , você ignora a versão do sistema que escolhe a interface a ser vinculada de forma diferente.
Isso é muito mais fácil e leve em recursos do sistema do que executar vários espaços de rede simultaneamente.
A página da Web acima fornece as duas instruções sobre como compilar o módulo e este link para pré- versões compiladas de 32 e 64 bits.
(Apenas para referência: eu sei que você não está interessado, mas o código pode ser facilmente modificado para forçar a ligação a uma porta específica ).
EDITAR :
Esqueci completamente que os jogos provavelmente usariam o UDP, enquanto o truque acima só funciona para conexões TCP. Estou deixando minha resposta no lugar, na esperança de ajudar alguém com problemas TCP desse tipo, mas como resposta a Timmos isso é completamente inútil.
Para compensar meu erro, estou passando a você um script (muito simples!) que escrevi e que configura um dos (possivelmente muitos) namespaces de rede.
#!/bin/bash
#
# This script will setup a network namespace with a macvlan
# which obtains its IP address via dhclient from the LAN on which the host is
# placed
#
set -x
# It will open an xterm window in the new network namespace; if anything
# else is required, change the statement below.
export XTERM1=xterm
# The script will temporarily activate ip forwarding for you. If you
# do not wish to retain this feature, you will have to issue, at the
# end of this session, the command
# echo 0 > /proc/sys/net/ipv4/ip_forward
# yourself.
###############################################################################
export WHEREIS=/usr/bin/whereis
# First of all, check that the script is run by root:
[ "root" != "$USER" ] && exec sudo $0 "$@"
if [ $# != 2 ]; then
echo "Usage $0 name action"
echo "where name is the network namespace name,"
echo " and action is one of start| stop| reload."
exit 1
fi
# Do we have all it takes?
IERROR1=0
IERROR2=0
IERROR3=0
export IP=$($WHEREIS -b ip | /usr/bin/awk '{print $2}')
export IPTABLES=$($WHEREIS -b iptables | /usr/bin/awk '{print $2}')
export XTERM=$($WHEREIS -b $XTERM1 | /usr/bin/awk '{print $2}')
if [ "x$IP" = "x" ] ; then
echo "please install the iproute2 package"
IERROR1=1
fi
if [ "x$IPTABLES" = "x" ] ; then
echo "please install the iptables package"
IERROR2=1
fi
if [ "x$XTERM" = "x" ] ; then
echo "please install the xterm package"
IERROR3=1
fi
if [[ $IERROR1 == 0 && $IERROR2 == 0 && $IERROR3 == 0 ]]
then
:
else
exit 1
fi
prelim() {
# Perform some preliminary setup. First, clear the proposed
# namespace name of blank characters; then create a directory
# for logging info, and a pid file in it; lastly, enable IPv4
# forwarding.
VAR=$1
export NNSNAME=${VAR//[[:space:]]}
export OUTDIR=/var/log/newns/$NNSNAME
if [ ! -d $OUTDIR ]; then
/bin/mkdir -p $OUTDIR
fi
export PID=$OUTDIR/pid$NNSNAME
echo 1 > /proc/sys/net/ipv4/ip_forward
}
start_nns() {
# Check whether a namespace with the same name already exists.
$IP netns list | /bin/grep $1 2> /dev/null
if [ $? == 0 ]; then
echo "Network namespace $1 already exists,"
echo "please choose another name"
exit 1
fi
# Here we take care of DNS
/bin/mkdir -p /etc/netns/$1
echo "nameserver 8.8.8.8" > /etc/netns/$1/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/netns/$1/resolv.conf
# The following creates the new namespace, and the macvlan interface
$IP netns add $1
$IP link add link eth0 mac$1 type macvlan mode bridge
# This assigns the macvlan interface, mac$1, to the new
# namespace, asks for an IP address via a call to dhclient,
# brings up this and the (essential) lo interface,
# creates a new terminal in the new namespace and
# stores its pid for the purpose of tearing it cleanly, later.
$IP link set mac$1 netns $1
$IP netns exec $1 /sbin/dhclient -v mac$1 1> /dev/null 2>&1
$IP netns exec $1 $IP link set dev lo up
$IP netns exec $1 su -c $XTERM $SUDO_USER &
$IP netns exec $1 echo "$!" > $PID
}
stop_nns() {
# Check that the namespace to be torn down really exists
$IP netns list | /bin/grep $1 2>&1 1> /dev/null
if [ ! $? == 0 ]; then
echo "Network namespace $1 does not exist,"
echo "please choose another name"
exit 1
fi
# This kills the terminal in the separate namespace and
# removes the file and the directory where it is stored.
/bin/kill -TERM $(cat $PID) 2> /dev/null 1> /dev/null
/bin/rm $PID
/bin/rmdir $OUTDIR
$IP netns del $1
# This deletes the file and direcotory connected with the DNSes.
/bin/rm /etc/netns/$1/resolv.conf
/bin/rmdir /etc/netns/$1
}
case $2 in
start)
prelim "$1"
start_nns $NNSNAME
;;
stop)
prelim "$1"
stop_nns $NNSNAME
;;
reload)
prelim "$1"
stop_nns $NNSNAME
prelim "$1"
start_nns $NNSNAME
;;
*)
# This removes the absolute path from the command name
NAME1=$0
NAMESHORT=${NAME1##*/}
echo "Usage:" $NAMESHORT "name action,"
echo "where name is the name of the network namespace,"
echo "and action is one of start|stop|reload"
;;
esac
Ele assume que sua interface principal é chamada eth0 (se a sua é chamada de forma diferente, altere a referência única para ela de acordo), e usa interfaces macvlan , o que significa que você pode use o script somente com uma conexão ethernet. Além disso, não precisa usar pontes.
Você inicia / interrompe um namespace de rede separado da seguinte maneira (eu chamo o script nns , mas você pode chamá-lo como quiser):
nns network_namespace_1 start
nns network_namespace_2 stop
Você pode ter tantos namespaces de rede diferentes quanto o seu servidor DHCP local permitir, já que cada interface do macvlan obtém um endereço IP do seu servidor DHCP da LAN. Se um namespace de rede com o mesmo nome já existir, você terá que escolher um nome diferente.
Todos os namespaces de rede podem se comunicar, cortesia da opção modo bridge em seu comando de criação. O script abre um terminal xterm no novo namespace de rede (eu gosto xterm , se você não pode mudar isso no topo do script) para que, de dentro o xterm você pode iniciar seus aplicativos.
Eu deixei a opção de depuração, set -x , no script, o que pode ajudá-lo a resolver algum problema inicial. Quando terminar, basta remover essa linha.
Felicidades.