Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assign an IPv4 address from the link-local subnet #833

Merged
merged 1 commit into from
Jan 28, 2021

Conversation

DimitriPapadopoulos
Copy link
Collaborator

@DimitriPapadopoulos DimitriPapadopoulos commented Jan 21, 2021

While the 192.0.2.0/24 TEST-NET-1 block would avoid collisions,
the 169.254.0.0/16 subnet described in RFC3927 has precisely been
specified precisely for such cases.

We should probably select "an address using a pseudo-random number
generator with a uniform distribution in the range from 169.254.1.0
to 169.254.254.255 inclusive", as described in RFC3927. However,
that would of course require more code and I'm lazy, but more
importantly it had been reported that FortiClient uses 169.254.2.1.
I'd rather use the same address as FortiClient.

Fixes #832.

While the 192.0.2.0/24 TEST-NET-1 block would avoid collisions,
the 169.254.0.0/16 subnet described in RFC3927 has been specified
precisely for such cases.

We should probably select "an address using a pseudo-random number
generator with a uniform distribution in the range from 169.254.1.0
to 169.254.254.255 inclusive" as described in RFC3927. However,
that would of course require more code and I'm lazy, but more
importantly it had been reported that FortiClient uses 169.254.2.1.
I'd rather use the same address as FortiClient.
Copy link
Collaborator

@mrbaseman mrbaseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Back in #280 we had a discussion if this address does really matter. We came to the conclusion that an arbitrary address could be used here for building up the communication over ppp. It's send as a proposal and the remote side uses it until dhcp has assigned a proper address.

The only problem I see is that a host route to this address is added via the ppp interface. The link local addresses can coexist on different links and they don't need explicit routing as far as I know.

I'm not sure what happens if this particular address is used on several interfaces and an explicit host route via one particular interface is added. Does the communication on the other interfaces still work, even if the routing table would suggest to send the packets over the ppp link?

@DimitriPapadopoulos
Copy link
Collaborator Author

Not certain about the issues you raise either. I don't want to modify something that works, it's just that this IP address might have an effect on the VPN speed on macOS Mojave.

@DimitriPapadopoulos
Copy link
Collaborator Author

@ultrafiber Do we really need to change 192.0.2.1169.254.2.1 in openfortivpn? Does the value of this IP address really have an effect on openfortivpn speed on macOS?

@mrbaseman
Copy link
Collaborator

I have given this change a try and here is the resulting routing table on Linux:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.XYZ.254 0.0.0.0         UG    100    0        0 enp2s0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp2s0
169.254.2.1     0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.XYZ.0   0.0.0.0         255.255.255.0   U     100    0        0 enp2s0
ABC.DEF.GHI.0   0.0.0.0         255.255.255.0   U     0      0        0 ppp0
ABC.DEF.OPQ.LMN 192.168.XYZ.254 255.255.255.255 UGH   0      0        0 enp2s0
ABC.DEF.OPQ.0   0.0.0.0         255.255.255.0   U     0      0        0 ppp0

While there is already a class B network route on the ethernet device for the link local network, openfortivpn adds a host route over the ppp interface.

So I must correct myself in this point:

The link local addresses can coexist on different links and they don't need explicit routing as far as I know.

There is a network route, and it would still work even if we add a host route to a single address of this network on a different interface.

My expectation is that nothing gets broken unless something else (another instance of openfortivpn?) uses 169.254.2.1 on a different interface. If there are any problems, the effect would probably be the same with the 192.0.2.1 address used so far - just for a different one. RFC 3927 discusses the topic Conflict detection and defense in Section 2.5 and Considerations for Multiple Interfaces in Section 3, but I'm not sure to which extend all this applies to the ppp link that we have in our case.

@DimitriPapadopoulos
Copy link
Collaborator Author

@mrbaseman If I understand you correctly, the situation won't be worse with 169.254.2.1 than with 192.0.2.1, will it? If so I suggest we apply this patch.

Then we could address Conflict detection and defense in Section 2.5 and Considerations for Multiple Interfaces in Section 3 later on. How soes this sound?

@mrbaseman
Copy link
Collaborator

Right, it's just that the 169.254.0.0/16 network might be in use more widely and collisions might happen more often.

But, given the fact that I'm connected with two instances of openfortivpn right now, which both use the 192.0.2.1, I agree that the situation won't be worse with 169.254.2.1.

@mrbaseman mrbaseman merged commit ba44ce1 into adrienverge:master Jan 28, 2021
@DimitriPapadopoulos DimitriPapadopoulos deleted the 169.254.2.1 branch January 28, 2021 23:23
@dlenski
Copy link

dlenski commented Feb 8, 2021

The address you're discussing is the address of the remote end of a tunnel (that is, a point-to-point connection). It's utterly meaningless and a correct implementation of a point-to-point connection (such as a VPN tunnel) shouldn't attempt to route the "address of the remote end of the tunnel" in any way. 🤷‍♂️

169.254.0.0/16 are link-local-addresses anyway, which means that they're unforwardable. Most likely Forti and other VPN providers have chosen 169.254.0.0/16 addresses as a crutch for their buggy implementations, because operating systems won't attempt to traffic to these addresses.

In all the protocols supported by OpenConnect, including in the in-development support for Fortinet… we just ignore "remote end of a tunnel" addresses that we receive, and it works just fine.

@DimitriPapadopoulos
Copy link
Collaborator Author

DimitriPapadopoulos commented Feb 8, 2021

@dlenski Yet it looks like pppd requires a remote IP address, and it has been reported 192.0.2.1169.254.2.1 does fix macOS slow VPN speeds. I am not 100% sure about that, as I have not reproduced this myself it has been reported only once. I don't know whether it's a pppdissue or a problem with FortiOS at the remote end.

On the other hand the pppd man page reads:

<local_IP_address>:<remote_IP_address>

Set the local and/or remote interface IP addresses. Either one may be omitted.

We do omit the local IP address. We could try omitting the remote IP address. I seem to recall pppd doesn't work without it, but I can try again.

@dlenski
Copy link

dlenski commented Feb 8, 2021

Yet it looks like pppd requires a remote IP address

If you don't give pppd a remote address, it will attempt to negotiate one using IPCP:

       <local_IP_address>:<remote_IP_address>
              Set the local and/or remote interface IP addresses.  Either one may be omitted.  The IP addresses can be specified with a host  name  or  in
              decimal dot notation (e.g. 150.234.56.78).  The default local address is the (first) IP address of the system (unless the noipdefault option
              is given).  The remote address will be obtained from the peer if not specified in any option.  Thus, in simple cases,  this  option  is  not
              required.   If  a  local and/or remote IP address is specified with this option, pppd will not accept a different value from the peer in the
              IPCP negotiation, unless the ipcp-accept-local and/or ipcp-accept-remote options are given, respectively.

I've verified that at least one Fortinet server is willing to do this negotiation (using ppp_protocols branch of OpenConnect).

… and it has been reported 192.0.2.1169.254.2.1 does fix macOS slow VPN speeds.

Yeah, this is probably because pppd is incorrectly trying to set up a route the peer's address. From man pppd (emphasis mine):

 When IPCP negotiation is completed successfully, pppd will  inform  the
 kernel  of  the  local  and  remote IP addresses for the ppp interface.
 **This is sufficient to create a host route to the  remote  end  of  the
 link,** which  will enable the peers to exchange IP packets.

☝️ This behavior is essentially undesirable for pppd used as a VPN tunnel, especially on Linux which can add a routing entry to a specific interface without reference to a gateway address. For a VPN, you really don't want a route for the peer's address created at all, because the OS never needs to route IP packets to that address.

tl;dr Setting it to a non-forwardable address definitely works as a bandaid. Reusing the same peer address 169.254.2.1 for multiple connections should not matter, because no conforming OS should be trying to send any IP packets to that address, anyway :-)

@DimitriPapadopoulos
Copy link
Collaborator Author

I have verified that omitting the remote IP address (:169.254.2.1:) does work.

Yet if I understand you correctly, the proper way to fix this is to stop forking pppd and embed minimal PPP code in openfortivpn instead (#650).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

192.0.2.1 → 169.254.2.1
3 participants