Linux環境において、あるNICに複数のIPアドレスを設定しようとしております。
例)
eth0 :192.168.11.10
eth0:1:192.168.11.20
上記IPアドレスを付与したNICより通信可能なサーバに対して
ある処理の場合は「192.168.11.10」より、異なる処理の場合は「192.168.11.20」より
といった具合に、処理に応じて通信元のIPアドレスを使い分けたいのですが
可能でしょうか?
※経緯
通信先のサーバ管理者より、処理毎に異なるIPアドレスを使用して
通信して欲しい旨、要望をいただいているためとなります。
しかし、対象の通信先サーバへ通信可能なNICが現在一つしかないため
対応方法について検討しております。
大変お手数ですが、ご教示の程よろしくお願いいたします。
(2019/11/17追記)
ご返答が遅くなり申し訳ございません。
また質問内容について不明確な部分が多く申し訳ございません。
通信元/通信先のOSはRedHatEnterpriseLinux6となります。
通信元から通信先に、TCPプロトコルにてデータの問い合わせを行います。
(この問い合わせ内容については具体的にはお伝えできません。
大変申し訳ございません。)
上記問い合わせを行うデータについて、データ毎に通信元IPを
変更してほしいと通信先のシステムより指示がありました。
そこで、先の質問の通り同一のサーバの同一のNICに異なる二つの
IPアドレスを設定して、データ毎に異なるIPアドレスを使用して
問い合わせることが出来るかどうかを確認しております。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
その「ある処理」と言うのが自分でプログラミングできる実行プログラムなのであれば、ソケットインターフェースのsetsockopt
でSO_BINDTODEVICE
オプションを指定することで、接続する際のネットワークインターフェースを指定することができます。(実際に使う際は、root権限が必要なようです)
socket - Linux Programmer's Manual (7)
そうではなく、既に配置されたデーモンや各種プログラムに適用したいというのであれば、それらプログラムがそれ相応のオプションを用意していない限り、できないと思われます。
投稿2019/11/13 06:02
編集2019/11/19 02:46総合スコア9256
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/11/17 13:40
退会済みユーザー
2019/11/17 18:13
2019/11/17 20:38
退会済みユーザー
2019/11/18 01:11
0
ベストアンサー
dodox86さんの回答のコメントという形で書いていたのですが、後から読んでみて、端折りすぎてる気がしたので、こちらで書かせて頂きます。ただし、(dodox86さんの意図はよく分かりませんが)コンセプトは同じだと思っています。
目的
同一IP、ポートのTCPのサーバに対して、クライアント側から状況に応じてIPを使い分けて通信したい
ネットワーク
冗長化されたネットワークならサーバ側や経路もIPが違うものだと思うが、そうではなく、同一IPなのにクライアント側だけ状況により異なるIPでTCPで通信する必要がある。そのような状況を再現するため、今回は確認用に以下のようなネットワークを構築した。
text
1(XXX.XXX.XXX.XXX/24):至インターネット 2サーバ(Windows 10 Home 64bit) 3(10.0.2.2/24):VirtualBox-NATアダプタ 4(192.168.56.1):VirtualBox-ホストオンリーアダプター 5|| 6(10.0.2.15/24): eth0 7(192.168.56.4): eth1 8クライアント(CentOS6 64bit)
クライアント側のネットワーク状況は以下のようになる。
text
1[user@centos6 ~]$ ip a 21: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 3 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 4 inet 127.0.0.1/8 scope host lo 5 inet6 ::1/128 scope host 6 valid_lft forever preferred_lft forever 72: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 8 link/ether MACアドレス brd ff:ff:ff:ff:ff:ff 9 inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0 10 inet6 IP6アドレス/64 scope link 11 valid_lft forever preferred_lft forever 123: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 13 link/ether MACアドレス brd ff:ff:ff:ff:ff:ff 14 inet 192.168.56.4/24 brd 192.168.56.255 scope global eth1 15 inet6 IP6アドレス/64 scope link 16 valid_lft forever preferred_lft forever 17[user@centos6 ~]$ ip r 1810.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 19192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.4 20169.254.0.0/16 dev eth0 scope link metric 1002 21169.254.0.0/16 dev eth1 scope link metric 1003 22default via 10.0.2.2 dev eth0
着目すべき点は、defaultな経路としては、eth0が選ばれているということ。
つまり、ホストにアクセスするときはeth1を使うが、それ以外の通信は全てeth0を使用する経路選択となる。
確認
上記ネットワークで、eth0に繋がるサーバIPに、クライアント側からeth0のIPとeth1のIPを状況に応じて使い分けて通信できるかどうかを確認する。
サーバ側
python3のhttp.serverを起動する。httpサーバなら何でもいい。pythonがたまたま入ってたので使用。
text
1python -m http.server --cgi 80
※cgi-bin/はこの説明では使用しない
クライアント側
以下のC++プログラムを使用する(中身はC)(client.cpp)。
C++
1#include <sys/types.h> 2#include <sys/socket.h> 3#include <netinet/in.h> 4#include <arpa/inet.h> 5#include <unistd.h> 6#include <cstdio> 7#include <cstring> 8 9int main(int argc, char* argv[]) 10{ 11 int s; 12 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0){ 13 fprintf(stderr, "Socket create failure!!!\n"); 14 return 1; 15 } 16 17 struct sockaddr_in server_addr; 18 struct sockaddr_in client_addr; 19 memset(&server_addr, 0, sizeof(server_addr)); 20 memset(&client_addr, 0, sizeof(client_addr)); 21 server_addr.sin_family = PF_INET; 22 server_addr.sin_port = htons(80); 23 inet_aton("10.0.2.2", &(server_addr.sin_addr)); 24 client_addr.sin_family = PF_INET; 25 client_addr.sin_port = htons(0); 26 inet_aton("192.168.56.4", &(client_addr.sin_addr)); 27 28 if (bind(s, (struct sockaddr *)&client_addr, sizeof(client_addr)) != 0) { 29 perror(argv[0]); 30 fprintf(stderr, "Can not bind.\n"); 31 return 1; 32 } 33 34 if (connect(s, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0){ 35 perror(argv[0]); 36 fprintf(stderr, "Can not connect.\n"); 37 return 1; 38 } 39 const char req[] = "GET / HTTP/1.1\r\nHost: 10.0.2.2\r\n\r\n"; 40 if (send(s, req, sizeof(req) - 1, 0) < 0) { 41 perror(argv[0]); 42 fprintf(stderr, "Can not send.\n"); 43 return 1; 44 } 45 shutdown(s, SHUT_WR); 46 char dummy[65536]; 47 int len; 48 do { 49 len = recv(s, &dummy, sizeof(dummy) - 1,0); 50 dummy[len] = '\0'; 51 printf("%s", dummy); 52 } while (len > 0); 53 close(s); 54 55 return 0; 56}
肝は普通見かけないクライアントソケットへのbind。ここでアドレスを指定している。
以下でコンパイル/実行出来る。
text
1$ g++ -g client.cpp 2$ ./a.out
※-gはデバッグ用のオプション
そして、今回は通信するパケットをキャプチャするためにtcpdumpを使用。上記の実行に先立って別端末から起動しておく。
text
1sudo tcpdump -v -i eth0 port 80
eth1から出ていくと思っていたが、経路設定どおり、eth0から出ていくため、eth0でキャプチャしている。
結果
eth0のキャプチャ結果
text
1tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 211:02:44.645870 IP (tos 0x0, ttl 64, id 37642, offset 0, flags [DF], proto TCP (6), length 60) 3 192.168.56.4.39408 > 10.0.2.2.http: Flags [S], cksum 0xb6a7 (correct), seq 192253294, win 14600, options [mss 1460,sackOK,TS val 35331684 ecr 0,nop,wscale 6], length 0 411:02:44.646718 IP (tos 0x0, ttl 64, id 37915, offset 0, flags [none], proto TCP (6), length 44) 5 10.0.2.2.http > 192.168.56.4.39408: Flags [S.], cksum 0x87ca (correct), seq 41408001, ack 192253295, win 65535, options [mss 1460], length 0 611:02:44.646754 IP (tos 0x0, ttl 64, id 37643, offset 0, flags [DF], proto TCP (6), length 40) 7 192.168.56.4.39408 > 10.0.2.2.http: Flags [.], cksum 0x667f (correct), ack 1, win 14600, length 0 811:02:44.647050 IP (tos 0x0, ttl 64, id 37644, offset 0, flags [DF], proto TCP (6), length 74) 9 192.168.56.4.39408 > 10.0.2.2.http: Flags [P.], cksum 0x04eb (incorrect -> 0xc8e1), seq 1:35, ack 1, win 14600, length 34 1011:02:44.647176 IP (tos 0x0, ttl 64, id 37916, offset 0, flags [none], proto TCP (6), length 40) 11 10.0.2.2.http > 192.168.56.4.39408: Flags [.], cksum 0x9f65 (correct), ack 35, win 65535, length 0 1211:02:44.647206 IP (tos 0x0, ttl 64, id 37645, offset 0, flags [DF], proto TCP (6), length 40) 13 192.168.56.4.39408 > 10.0.2.2.http: Flags [F.], cksum 0x665c (correct), seq 35, ack 1, win 14600, length 0 1411:02:44.647344 IP (tos 0x0, ttl 64, id 37917, offset 0, flags [none], proto TCP (6), length 40) 15 10.0.2.2.http > 192.168.56.4.39408: Flags [.], cksum 0x9f64 (correct), ack 36, win 65535, length 0 1611:02:44.660887 IP (tos 0x0, ttl 64, id 37919, offset 0, flags [none], proto TCP (6), length 195) 17 10.0.2.2.http > 192.168.56.4.39408: Flags [P.], cksum 0x08d7 (correct), seq 1:156, ack 36, win 65535, length 155 1811:02:44.660909 IP (tos 0x0, ttl 64, id 37920, offset 0, flags [none], proto TCP (6), length 1460) 19 10.0.2.2.http > 192.168.56.4.39408: Flags [.], cksum 0x1b39 (correct), seq 156:1576, ack 36, win 65535, length 1420 2011:02:44.660961 IP (tos 0x0, ttl 64, id 37646, offset 0, flags [DF], proto TCP (6), length 40) 21 192.168.56.4.39408 > 10.0.2.2.http: Flags [.], cksum 0x6211 (correct), ack 156, win 15544, length 0 2211:02:44.661035 IP (tos 0x0, ttl 64, id 37647, offset 0, flags [DF], proto TCP (6), length 40) 23 192.168.56.4.39408 > 10.0.2.2.http: Flags [.], cksum 0x5121 (correct), ack 1576, win 18460, length 0 2411:02:44.661092 IP (tos 0x0, ttl 64, id 37921, offset 0, flags [none], proto TCP (6), length 1460) 25 10.0.2.2.http > 192.168.56.4.39408: Flags [.], cksum 0xd410 (correct), seq 1576:2996, ack 36, win 65535, length 1420 2611:02:44.661097 IP (tos 0x0, ttl 64, id 37922, offset 0, flags [none], proto TCP (6), length 1460) 27 10.0.2.2.http > 192.168.56.4.39408: Flags [.], cksum 0xfea2 (correct), seq 2996:4416, ack 36, win 65535, length 1420 2811:02:44.661098 IP (tos 0x0, ttl 64, id 37923, offset 0, flags [none], proto TCP (6), length 799) 29 10.0.2.2.http > 192.168.56.4.39408: Flags [FP.], cksum 0xc6f4 (correct), seq 4416:5175, ack 36, win 65535, length 759 3011:02:44.661123 IP (tos 0x0, ttl 64, id 37648, offset 0, flags [DF], proto TCP (6), length 40) 31 192.168.56.4.39408 > 10.0.2.2.http: Flags [.], cksum 0x407d (correct), ack 2996, win 21300, length 0 3211:02:44.661168 IP (tos 0x0, ttl 64, id 37649, offset 0, flags [DF], proto TCP (6), length 40) 33 192.168.56.4.39408 > 10.0.2.2.http: Flags [.], cksum 0x2fd9 (correct), ack 4416, win 24140, length 0 3411:02:44.661208 IP (tos 0x0, ttl 64, id 37650, offset 0, flags [DF], proto TCP (6), length 40) 35 192.168.56.4.39408 > 10.0.2.2.http: Flags [.], cksum 0x21c9 (correct), ack 5176, win 26980, length 0
一部チェックサムがincorrectになっているが、通信自体は出来ており、eth0を使用し、アドレスにはeth1のアドレスが使用されている。サーバ側でアドレスを取ろうとしたが、NATでIP偽装されており、127.0.0.1になっていたため、そちらは未確認。
投稿2019/11/18 02:07
編集2019/11/18 02:14退会済みユーザー
総合スコア0
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。