ネットワークネームスペースとパブリックIP

ネットワークネームスペースとパブリックIP

まず、私は読んだ。ネットワークネームスペースに関する素晴らしい記事です。だから私はネットワークネームスペースの機能と設定方法をある程度知っています。

私が直面している実際の問題は次のとおりです。

  • 実際のコンピュータでLANモードでいくつかのValveゲームサーバー(CS、CS:GO、TF2)を実行したいです。したがって、LAN上のすべてのクライアントがLAN上のすべてのサーバーを一覧表示したいと思います。これは、ip:portに手動で接続するのと比較して最高のユーザーエクスペリエンスだからです。
  • クライアントソフトウェアはポート27015 - 27020にブロードキャストしてLANサーバーを見つけます。したがって、サーバーの実行に使用できるポートは合計6つです。それ以外の場合、サーバーはLANブラウザに表示されません。ただし、サーバーが6つ以上あるため、同じ物理サーバーに1つ以上のIPを使用する必要があります。実際の計画は、ゲームごとに1つのIPを保持することです。
  • 繰り返しますが、ゲームサーバーに特定のIPにバインドするように指示することはできません。これは、サーバーが明示的にLANサーバーのように実行するように指示しても、クライアントのLANブラウザに表示されないためです。

(CS 1.6、CSGO、またはTF2サーバーを実行したい人はここで「+ ip <ip address>」の問題を認識できます)

ゲームサーバーに特定のIPアドレスにバインドするように指示できないため、複数のIPを使用して問題を解決することはできません。ソフトウェアは常にデフォルトのIPを使用するため、機能しません。 (ポートの競合またはソフトウェアが27020を超えるポートを占有し、LANブラウザでサーバーが表示されなくなる)

私はネットワークネームスペース(ゲームごとに1つのネットワークネームスペース)を使用してこの問題を解決したいと思います。

  • 「csgo」ネットワークネームスペースで5つのCSGOインスタンスを実行します。 (27015-27019)
  • 「tf2」ネットワークネームスペースでTF2インスタンスを1つ実行します。 (27015)
  • 「cs16」ネットワークネームスペースでCS 1.6インスタンスを2つ実行します。 (27015-27016)

ネームスペースでゲームソフトウェアを実行するため、ソフトウェアは1つのIPのみを表示し、自動的にそのIPを採用します。 (まあ、それは私の考えです!)。

合計4つのネットワーク名前空間(「default」、「csgo」、「tf2」、および「cs16」)があります。構成は次のとおりです。

- eth0 / 192.168.0.160 ("default" ns, internet access)
- veth0:0 / 192.168.0.161 ("default" ns) <======> veth0:1 / 192.168.0.171 ("csgo" NS)
- veth1:0 / 192.168.0.162 ("default" ns) <======> veth1:1 / 192.168.0.172 ("tf2" NS)
- veth2:0 / 192.168.0.163 ("default" ns) <======> veth2:1 / 192.168.0.173 ("cs16" NS)

今問題はこれがうまくいくかどうかです。 「csgo」ネームスペースでCSGOサーバーソフトウェアを実行している場合、LANサーバーのパブリックIPは192.168.0.171ですか?それとも192.168.0.160ですか?それとも192.168.0.161でしょうか?上記のように、9台のサーバーがすべてLANブラウザに表示されるようにするには、各ゲームに別々のIPアドレスを割り当てる必要があります。

そうでない場合は、実際にネットワーク名前空間を使用してこの問題を解決できますか?

ベストアンサー1

アプリケーションを特定のIPアドレスにバインドすることは非常に困難な問題です。すべてのアプリケーションが同じではありません。SSHバインドするIPアドレスを指定できます。-雨オプション。たとえば、FirefoxとChromeはこれに影響されません。

幸いにも解決策があります:この男すでに編集済みバインディングファイルシステムライブラリを使用すると、コマンドラインでバインドアドレスを次のように指定できます。

$ BIND_ADDR="192.0.2.100" LD_PRELOAD=/usr/lib/bind.so firefox

あらかじめロードして製本共有オブジェクトを使用すると、別の方法でバインドするインターフェイスのシステムバージョンを選択する必要がなくなります。

これは、複数のネットワークスペースを同時に実行するよりもはるかに簡単で、システムリソースをはるかに少なく使用します。

上記のWebページでは、モジュールをコンパイルする方法とこのリンクプリコンパイルされた32ビット版と64ビット版。

(注:興味はありませんが、コードを簡単に修正して特定の項目に強制的にバインドできます。ポート)。

編集する:

私はゲームがUDPを使用する可能性が高く、上記のトリックはTCP接続でのみ機能するという事実を完全に忘れました。この種のTCP問題を抱えている人に役立つことを願って答えを残していますが、Timmosへの答えでは完全に役に立ちません。

私の間違いを取り除くために1つ(おそらく複数の)ネットワークネームスペースを設定する私が書いた(非常に単純な!)スクリプトを渡します。

#!/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

基本インターフェイスが呼び出されると仮定します。イーサネット0(呼び出し方法が異なる場合は、それに応じて単一の参照を変更してください)マクエバーランドインターフェイス、これはスクリプトが利用可能であることを意味します。ただイーサネット接続があります。また、ネットワークブリッジを使用する必要はありません。

次のように別々のネットワーク名前空間を開始/停止できます。ニューラルネットワーク、しかし、好きなように呼び出すことができます):

nns network_namespace_1 start
nns network_namespace_2 stop

各macvlanインターフェースはLAN DHCPサーバーからIPアドレスを取得するため、ローカルDHCPサーバーが許可するのと同じくらい多様なネットワーク名前空間を持つことができます。同じ名前のネットワーク名前空間がすでに存在する場合は、別の名前を選択する必要があります。

すべてのネットワーク名前空間は互いに通信できます。パターンブリッジ生成コマンドのオプション。このスクリプトはxterm新しいネットワークネームスペースの端末(私はxtermそうでない場合は、スクリプトの上部でこれを変更してxtermでアプリケーションを起動できます。

デバッグオプションをオフにしました。セット-x、スクリプト内のいくつかの初期の問題を解決するのに役立ちます。完了したら、その行を削除します。

乾杯。

おすすめ記事