Home>

I am trying to set multiple IP addresses for a NIC in a Linux environment.

Example)
eth0: 192.168.11.10
eth0: 1: 192.168.11.20

For servers that can communicate from the NIC with the above IP address
For some processes, from "192.168.11.10", for different processes, from "192.168.11.20"
I would like to use the IP address of the communication source properly depending on the processing etc.
Is it possible?

※ Background
Use a different IP address for each process from the server administrator of the communication destination
This is because there is a request to communicate.
However, there is currently only one NIC that can communicate with the target server.
We are investigating how to respond.

Thank you very much for your teaching.

(Added on November 17, 2019)
Sorry for the late reply.
I am sorry for the many unclear points about the question.

The source/destination OS is RedHatEnterpriseLinux6.
Inquires data from the communication source to the communication destination using the TCP protocol.
(We can't give you any specific details about this inquiry.
Sorry. )

For the data to be inquired above, specify the source IP for each data
There was an instruction from the communication destination system to change it.
Therefore, two different
for the same NIC of the same server as the previous question Set IP address and use different IP address for each data
We are checking whether we can make an inquiry.

  • Answer # 1

    If the "some process" is an executable program that you can program yourself, connect by specifying theSO_BINDTODEVICEoption in the socket interfacesetsockoptYou can specify the network interface to use. (In actual use, root privilege is required.Like)

    socket-Linux Programmer's Manual (7)

    Rather, if you want to apply it to already deployed daemons and programs, you probably won't be able to do so unless those programs have the appropriate options.

  • Answer # 2

    I wrote in the form of a comment from dodox86's answer, but I read it later and I felt that it was too broken. However, the concept is the same (although dodox86-san's intention is not well understood).

    Purpose

    I want to communicate with a TCP server with the same IP and port, using different IPs from the client according to the situation

    Network

    If the network is redundant, I think that the server side and the route are different IP, but it is not so, but only the client side needs to communicate with TCP with different IP depending on the situation. In order to reproduce such a situation, the following network was constructed for confirmation this time.

    (XXX.XXX.XXX.XXX/24):
    Server (Windows 10 Home 64bit)
    (10.0.2.2/24):VirtualBox-NAT adapter
    (192.168.56.1): VirtualBox-Host Only Adapter
    ||
    (10.0.2.15/24): eth0
    (192.168.56.4): eth1
    Client (CentOS6 64bit)

    The network status on the client side is as follows.

    [user @ centos6 ~] $ip a
    1: lo:mtu 65536 qdisc noqueue state UNKNOWN
        link/loopback 00: 00: 00: 00: 00: 00 brd 00: 00: 00: 00: 00: 00
        inet 127.0.0.1/8 scope host lo
        inet6 :: 1/128 scope host
           valid_lft forever preferred_lft forever
    2: eth0:mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether MAC address brd ff: ff: ff: ff: ff: ff
        inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
        inet6 IP6 address/64 scope link
           valid_lft forever preferred_lft forever
    3: eth1:mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether MAC address brd ff: ff: ff: ff: ff: ff
        inet 192.168.56.4/24 brd 192.168.56.255 scope global eth1
        inet6 IP6 address/64 scope link
           valid_lft forever preferred_lft forever
    [user @ centos6 ~] $ip r
    10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
    192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.4
    169.254.0.0/16 dev eth0 scope link metric 1002
    169.254.0.0/16 dev eth1 scope link metric 1003
    default via 10.0.2.2 dev eth0

    It should be noted that eth0 is selected as the default route.
    In other words, eth1 is used when accessing the host, but all other communication is route selection using eth0.

    Confirm

    Check whether the client side can use the eth0 IP and the eth1 IP properly for the server IP connected to eth0 in the above network.

    Server side

    Start http.server of python3. Any http server is acceptable. Used because python happened to happen.

    python -m http.server --cgi 80


    * Cgi-bin/is not used in this explanation

    Client side

    Use the following C ++ program (content is C) (client.cpp).

    # include
    #include
    #include
    #include 
    #include
    #include#include
    int main (int argc, char * argv [])
    {
        int s;
        if ((s = socket (AF_INET, SOCK_STREAM, 0))<0) {
            fprintf (stderr, "Socket create failure !!! \ n");
            return 1;
        }
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
        memset (&server_addr, 0, sizeof (server_addr));
        memset (&client_addr, 0, sizeof (client_addr));
        server_addr.sin_family = PF_INET;
        server_addr.sin_port = htons (80);
        inet_aton ("10.0.2.2",&(server_addr.sin_addr));
        client_addr.sin_family = PF_INET;
        client_addr.sin_port = htons (0);
        inet_aton ("192.168.56.4",&(client_addr.sin_addr));
        if (bind (s, (struct sockaddr *)&client_addr, sizeof (client_addr))! = 0) {
            perror (argv [0]);
            fprintf (stderr, "Can not bind. \ n");
            return 1;
        }
        if (connect (s, (struct sockaddr *)&server_addr, sizeof (server_addr))! = 0) {
            perror (argv [0]);
            fprintf (stderr, "Can not connect. \ n");
            return 1;
        }
        const char req [] = "GET/HTTP/1.1 \ r \ nHost: 10.0.2.2 \ r \ n \ r \ n";
        if (send (s, req, sizeof (req)-1, 0)<0) {
            perror (argv [0]);
            fprintf (stderr, "Can not send. \ n");
            return 1;
        }
        shutdown (s, SHUT_WR);
        char dummy [65536];
        int len;
        do {
            len = recv (s,&dummy, sizeof (dummy)-1,0);
            dummy [len] = '\ 0';
            printf ("% s", dummy);
        } while (len>0);
        close (s);
        return 0;
    }

    Bind to client sockets that you don't normally see. The address is specified here.

    You can compile/execute below.

    $g ++ -g client.cpp
    $./a.out

    *-g is an option for debugging

    And this time, tcpdump is used to capture the communication packet. Prior to the above execution, start from another terminal.

    sudo tcpdump -v -i eth0 port 80

    I thought I was going to exit from eth1, but it was captured by eth0 because it went out from eth0 according to the route setting.

    Result

    Eth0 capture result

    tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
    11: 02: 44.645870 IP (tos 0x0, ttl 64, id 37642, offset 0, flags [DF],
     proto TCP (6), length 60)
        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
    11: 02: 44.646718 IP (tos 0x0, ttl 64, id 37915, offset 0, flags [none],
     proto TCP (6), length 44)
        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
    11: 02: 44.646754 IP (tos 0x0, ttl 64, id 37643, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [.],
     cksum 0x667f (correct), ack 1, win 14600, length 0
    11: 02: 44.647050 IP (tos 0x0, ttl 64, id 37644, offset 0, flags [DF],
     proto TCP (6), length 74)
        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
    11: 02: 44.647176 IP (tos 0x0, ttl 64, id 37916, offset 0, flags [none],
     proto TCP (6), length 40)
        10.0.2.2.http>192.168.56.4.39408: Flags [.],
     cksum 0x9f65 (correct), ack 35, win 65535, length 0
    11: 02: 44.647206 IP (tos 0x0, ttl 64, id 37645, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [F.],
     cksum 0x665c (correct), seq 35, ack 1, win 14600, length 0
    11: 02: 44.647344 IP (tos 0x0, ttl 64, id 37917, offset 0, flags [none],
     proto TCP (6), length 40)
        10.0.2.2.http>192.168.56.4.39408: Flags [.],
     cksum 0x9f64 (correct), ack 36, win 65535, length 0
    11: 02: 44.660887 IP (tos 0x0, ttl 64, id 37919, offset 0, flags [none],
     proto TCP (6), length 195)
        10.0.2.2.http>192.168.56.4.39408: Flags [P.],
     cksum 0x08d7 (correct), seq 1: 156, ack 36, win 65535, length 155
    11: 02: 44.660909 IP (tos 0x0, ttl 64, id 37920, offset 0, flags [none],proto TCP (6), length 1460)
        10.0.2.2.http>192.168.56.4.39408: Flags [.],
     cksum 0x1b39 (correct), seq 156: 1576, ack 36, win 65535, length 1420
    11: 02: 44.660961 IP (tos 0x0, ttl 64, id 37646, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [.],
     cksum 0x6211 (correct), ack 156, win 15544, length 0
    11: 02: 44.661035 IP (tos 0x0, ttl 64, id 37647, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [.],
     cksum 0x5121 (correct), ack 1576, win 18460, length 0
    11: 02: 44.661092 IP (tos 0x0, ttl 64, id 37921, offset 0, flags [none],
     proto TCP (6), length 1460)
        10.0.2.2.http>192.168.56.4.39408: Flags [.],
     cksum 0xd410 (correct), seq 1576: 2996, ack 36, win 65535, length 1420
    11: 02: 44.661097 IP (tos 0x0, ttl 64, id 37922, offset 0, flags [none],
     proto TCP (6), length 1460)
        10.0.2.2.http>192.168.56.4.39408: Flags [.],
     cksum 0xfea2 (correct), seq 2996: 4416, ack 36, win 65535, length 1420
    11: 02: 44.661098 IP (tos 0x0, ttl 64, id 37923, offset 0, flags [none],
     proto TCP (6), length 799)
        10.0.2.2.http>192.168.56.4.39408: Flags [FP.],
     cksum 0xc6f4 (correct), seq 4416: 5175, ack 36, win 65535, length 759
    11: 02: 44.661123 IP (tos 0x0, ttl 64, id 37648, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [.],
     cksum 0x407d (correct), ack 2996, win 21300, length 0
    11: 02: 44.661168 IP (tos 0x0, ttl 64, id 37649, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [.],
     cksum 0x2fd9 (correct), ack 4416, win 24140, length 0
    11: 02: 44.661208 IP (tos 0x0, ttl 64, id 37650, offset 0, flags [DF],
     proto TCP (6), length 40)
        192.168.56.4.39408>10.0.2.2.http: Flags [.],
     cksum 0x21c9 (correct), ack 5176, win 26980, length 0

    Some checksums are incorrect, but communication is possible, eth0 is used, and the address of eth1 is used. I tried to get an address on the server side, but it was unconfirmed because it was IP spoofed by NAT and became 127.0.0.1.

  • Answer # 3

    I don't know what is "a certain process" and "different process".
    If each process works with NIC specification, it will be possible
    It's usually difficult to separate with somehow