> On Apr 25, 2017, at 5:45 PM, Benjamin Mahler <bmah...@apache.org> wrote:
> 
> Thanks, this sounds good, just want to clarify a few things:
> 
> (1) When you say "bind" the UPID IP address to the address of the message
> sender, you specifically just mean disallowing messages where they do not
> match?

Correct.

> 
> (2) Why IP and not port? Or do you think port enforcement would be
> optionally useful on top of IP enforcement?

The UPID contains the listener port, not the sender port, so they are 
guaranteed not to match.

> 
> (3) What will libprocess do when it finds the IP doesn't match? Drop and
> log?

It responds with an InternalServerError.

> 
> On Thu, Apr 20, 2017 at 9:16 AM, James Peach <jor...@gmail.com> wrote:
> 
>> 
>>> On Apr 19, 2017, at 5:24 PM, Benjamin Mahler <bmah...@apache.org> wrote:
>>> 
>>> It's not obvious to me what all of the implications are. I feel we need
>> a more comprehensive proposal here, can you do a small write up that shows
>> you've thought through all the implications?
>> 
>> Ok, let me summarize ...
>> 
>> In libprocess, actors (processes) are globally identified by their UPID.
>> The UPID is a string of the format <ID>@<IP address>:port. When libprocess
>> actors communicate, they listen on a single IP address and port and claim
>> this endpoint in their UPID. The expectation of other actors is that they
>> can send messages to this actor by connecting to the endpoint claimed in
>> the UPID. Note that the peer address used to send messages is not the UPID,
>> but whichever source address:port that the sender happened to bind.
>> 
>> Due to various network configurations (eg. NAT, multihoming), situations
>> arise where a receiver is not able to easily predict which IP address it
>> needs to claim in its UPID such that senders will be able to connect to it.
>> This leads to the need for configuration options like LIBPROCESS_IP
>> (specify the address to listen on) and LIBPROCESS_ADVERTISE_IP (specify the
>> address in the UPID).
>> 
>> The fundamental problem this proposal attempts to mitigate is the
>> libprocess has no mechanism that can authenticate a UPID. This means that
>> unless the network fabric is completely trusted, anyone with access to the
>> network can inject arbitrary messages into any libprocess actor,
>> impersonating any other actor.
>> 
>> This proposal adds an optional libprocess setting to bind the IP address
>> claimed in the UPID to the IP address of the message sender. This is a
>> receiver option, where the receiver compared the result of getpeername(2)
>> with the UPID from the libprocess message. The IP address is required to
>> match, but the port and ID are allowed to differ. In practice, this means
>> that libprocess actors are required to send from the same IP address they
>> are listening on. So to impersonate a specific UPID you have to be able to
>> send the message from the same IP address the impersonatee is using (ie. be
>> running on the same host), which increases the difficulty of impersonation.
>> 
>> In our deployments, all the cluster members are single-homed and remote
>> access to the system is restricted. We know in advance that neither
>> LIBPROCESS_IP nor LIBPROCESS_ADVERTISE_IP options are required. We have
>> some confidence that we control the services running on cluster hosts. If
>> we bind the UPID address to the socket peer address, then UPID
>> impersonation requires that malicious code is already running on a cluster
>> host, at which point we probably have bigger problems.
>> 
>> In terms of testing, all the test suite passes except for 
>> ExamplesTest.DiskFullFramework.
>> This test uses the LIBPROCESS_IP option to bind to the lo0 interface, which
>> can result in the UPID claiming 127.0.0.1 but getpeername(2) returning one
>> of the hosts external IP addresses. This is really just one type of a
>> multi-homed host configuration, so it demonstrates that this configuration
>> will break.
>> 
>>> 
>>> E.g. how does this affect the use of proxies, multihomed hosts, our
>> testing facilities for message spoofing, etc.
>>> 
>>> On Tue, Apr 18, 2017 at 2:07 PM, James Peach <jor...@gmail.com> wrote:
>>> 
>>>> On Apr 7, 2017, at 8:47 AM, Jie Yu <yujie....@gmail.com> wrote:
>>>> 
>>>> + BenM
>>>> 
>>>> James, I don't have immediate context on this issue. BenM will be back
>> next
>>>> week and he should be able to give you more accurate feedback.
>>> 
>>> 
>>> I updated the review chain (from https://reviews.apache.org/r/58517/).
>> Is anyone able to shepherd this?
>>> 
>>> 
>>>> 
>>>> - Jie
>>>> 
>>>> On Fri, Apr 7, 2017 at 8:37 AM, James Peach <jor...@gmail.com> wrote:
>>>> 
>>>>> 
>>>>>> On Apr 5, 2017, at 5:42 PM, Jie Yu <yujie....@gmail.com> wrote:
>>>>>> 
>>>>>> One comment here is that:
>>>>>> 
>>>>>> We plan to support libprocess communication using domain socket. In
>> other
>>>>>> words, we plan to make UPID a socket addr. Can we make sure this
>> approach
>>>>>> also works for the case where UPID is a unix address in the future?
>> For
>>>>>> instance, what will `socket->peer();` returns for domain socket?
>>> 
>>> This would probably work, but it depends on the lib process
>> implementation. Since this is (default false) option, I this it is OK for
>> now. I'll be happy to revisit when libprocess messaging supports domain
>> sockets.
>>> 
>>>>> 
>>>>> I can look into that.
>>>>> 
>>>>> So you would consider this approach a reasonable mitigation?
>>>>> 
>>>>>> 
>>>>>> - Jie
>>>>>> 
>>>>>> On Wed, Apr 5, 2017 at 3:27 PM, James Peach <jor...@gmail.com>
>> wrote:
>>>>>> 
>>>>>>> Hi all,
>>>>>>> 
>>>>>>> Currently, libprocess messages contain a UPID, which is send by the
>> peer
>>>>>>> in the HTTP message header. There's no validation of this, so
>> generally
>>>>>>> messages are trusted to be from the UPID they claim to be.
>>>>>>> 
>>>>>>> As an RFC, I've pushed https://reviews.apache.org/r/58224/. This
>> patch
>>>>>>> constrains the UPID to not change for the lifetime of the socket
>>> 
>>> I dropped this constraint. There are DiskQuotaTest.SlaveRecovery depends
>> on the UPID being able to change. More accurately, libprocess only matches
>> on the address portion of the UPID when finding a socket to use, and for
>> now I don't think this change is beneficial enough to break that assumption.
>>> 
>>>>>>> , and
>>>>> also
>>>>>>> enforces that the the IP address portion of the UPID matches the
>> peer
>>>>>>> socket address. This makes UPIDs more reliable, but the latter check
>>>>> would
>>>>>>> break existing configurations. I'd appreciate any feedback on
>> whether
>>>>> this
>>>>>>> is worth pursuing at the lib process level and whether people feel
>> that
>>>>>>> this specific mitigation is worthwhile.
>>>>>>> 
>>>>>>> thanks,
>>>>>>> James
>>>>> 
>>>>> 
>>> 
>>> 
>> 
>> 

Reply via email to