There are a few things to note when using OpenVPN:

  1. If the OpenVPN client sends forward packets instead of its virtual IP address, SNAT must be done before the data enters the virtual network card. Otherwise, the OpenVPN server will reject such packets.

  2. If the TAP virtual network adapter mode is used, the virtual IP address of the OpenVPN server must be set as the gateway, not only an egress device, because the TAP mode requires ARP. If the destination address is not on the OpenVPN server or even if it is on the OpenVPN server but its arp_ignore is set to a different value, ARP will fail to send data.

  3. When the client-to-client mode is enabled and the Tun mode is used, do not assume that all the clients and servers are in the same subnet. The Tun mode is point-to-point and does not have the concept of subnet. Therefore, one client or its subsequent hosts can access the resources behind c2 of another client. You cannot set the gateway to C2 unless you do a complex source/destination address translation because the OpenVPN server will not recognize the destination address after C2.

  4. If tap mode is used and C2C is enabled, all the clients and servers form a virtual subnet, and the internal ARP can be circulated. As a virtual Ethernet, the OpenVPN server is the same as a real Ethernet switch. Any client or server can be set as a gateway. In this sense, the OpenVPN server is a Layer 3 switch.

The code is in multi_process_incoming_link:

bool multi_process_incoming_link (struct multi_context *m, struct multi_instance *instance, const unsigned int mpp_flags)

{

	struct context *c;

	struct mroute_addr src, dest;

	unsigned int mroute_flags;

	struct multi_instance *mi;

	bool ret = true; .if(BLEN (&c->c2.buf) > 0) { process_incoming_link (c); // This operation is decrypted, the VPN as the client segment only calls this function without the following address judgmentif(TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TUN) { mroute_flags = mroute_extract_addr_from_packet (&src, &dest, NULL, NULL, &c->c2.to_tun, DEV_TYPE_TUN); // Ensure that the source IP address is a client of its own, that is, to translate the source address on the client sideelse if (multi_get_instance_by_virtual_addr (m, &src, true)! = m->pending) { ... C ->c2.to_tun. Len = 0; // No more writing to virtual nic}else if(m->enable_c2c) { ... // In multicast mode, the multicast flag is set based on the IP address type. Tun does not have ARPelse{// Use the destination IP address as the key value to find the client whose destination address is the virtual address. If the destination address translation is not done, no client can be found here. The final data will be sent to the virtual nic, waiting for the kernel standard routing system route. Mi = multi_get_instance_by_virtual_addr (m, &dest,true);

		      			if(mi) { multi_unicast (m, &c->c2.to_tun, mi); Register_activity (c, BLEN(&c->c2.to_tun)); c->c2.to_tun.len = 0; }}}}else if(TUNNEL_TYPE (m->top.c1.tuntap) == DEV_TYPE_TAP) { mroute_flags = mroute_extract_addr_from_packet (&src, &dest, NULL, NULL, &c->c2.to_tun, DEV_TYPE_TAP);if (multi_learn_addr (m, m->pending, &src, 0) == m->pending) {

				if(m->enable_c2c) {// The following is the broadcast/multicast situation, for example, in tap mode arp is broadcast, mroute_extract_addr_ether processing ARP, set the multicast flag, OpenVPN, multicast and broadcast processingif (mroute_flags & (MROUTE_EXTRACT_BCAST|MROUTE_EXTRACT_MCAST)) {

			      			multi_bcast (m, &c->c2.to_tun, m->pending, NULL);

			    		} elseMi = multi_get_instance_by_virtual_addr (m, &dest,false);

			      			if(mi) { multi_unicast (m, &c->c2.to_tun, mi); Register_activity (c, BLEN(&c->c2.to_tun)); c->c2.to_tun.len = 0; }}}... }else{ c->c2.to_tun.len = 0; }}} // All other cases are written to the virtual network card. Once written to the virtual network card, the direction of the packet is no longer controlled by OpenVPN. Ret = multi_process_POST (m, M -> PENDING, MPP_FLAGS); . }Copy the code

In multi_process_incoming_TUN there is the following judgment:

multi_set_pending (m, multi_get_instance_by_virtual_addr (m, &dest, dev_type == DEV_TYPE_TUN));

if(M -> Pending) --> Subsequent processingCopy the code

This is to check the validity of the destination address. As an OpenVPN server, packets from the virtual network adapter are sent to the OpenVPN client. Therefore, you need to check the destination address, which is the opposite of multi_process_incoming_link.

In TUN mode, routes are routed by IP address, and in TAP mode, routes are routed by MAC address. On the client side, there is no such complex judgment on the server side, just through the process of “in-tun–out-link- encryption, in-link–out-tun- decryption”





reference