Skip to content

Commit

Permalink
Added debug logs and mapped-IPv4 address matching.
Browse files Browse the repository at this point in the history
  • Loading branch information
gotthardp committed Oct 27, 2015
1 parent 4b4ae99 commit aeb3fd0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# RabbitMQ plug-in for client authorization based on source IP address

## History
* 0.1.1 (Oct 27, 2015) Bugfix release.
* IPv4-mapped IPv6 addresses now match the respective IPv4 address.
* Added some debug logs to hunt the Issue #2.
* Authenticate against remote (client) address instead of local (server) address.
* 0.1.0 (Nov 14, 2014) First release. Compatible with stable RabbitMQ 3.5.x only.

## Configuration
Expand Down Expand Up @@ -67,6 +71,10 @@ For example:
This will allow users with the tag `ip-private` to login from private networks
only. Other users will be able to login from any network.

The IPv4 mask (e.g. 192.168.0.0) will match an IPv4 address only.
The IPv4-mapped IPv6 mask (e.g. ::FFFF:192.168.0.0) will match both IPv4 and
IPv6 addresses.


## Build Instructions

Expand Down
23 changes: 16 additions & 7 deletions src/rabbit_auth_backend_ip_range.erl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ user_login_authorization(_Username) ->

check_vhost_access(#auth_user{tags = Tags}, _VHostPath, Sock) ->
Address = extract_address(Sock),
% rabbit_log:info("Checking address ~s~n", [inet_parse:ntoa(Address)]),

% filter out applicable masks
case lists:filtermap(
Expand Down Expand Up @@ -58,11 +57,12 @@ check_masks(Address, Masks) ->
if
R == false ->
rabbit_log:warning("Address ~s not matching any of [ ~s]~n",
[inet_parse:ntoa(Address),
lists:flatten(lists:foldr(fun(Mask, Acc) ->
[io_lib:format("~s ", [Mask]) | Acc] end, [], Masks))]),
[inet_parse:ntoa(Address), format_masks(Masks)]),
false;
true -> true
true ->
rabbit_log:debug("Address ~s matching [ ~s]~n",
[inet_parse:ntoa(Address), format_masks(Masks)]),
true
end.

check_resource_access(#auth_user{}, #resource{}, _Permission) -> true.
Expand All @@ -78,6 +78,10 @@ extract_address(Sock) ->
{ok, {Address, _Port}} = rabbit_net:peername(Sock),
Address.

format_masks(Masks) ->
lists:flatten(lists:foldr(fun(Mask, Acc) ->
[io_lib:format("~s ", [Mask]) | Acc] end, [], Masks)).

compile_addrmask(AddrMask) ->
case string:tokens(binary_to_list(AddrMask), "/\\") of
[Addr] ->
Expand All @@ -95,13 +99,18 @@ compile_address(Addr) ->
{error, _} -> throw({error, einval})
end.

address_to_binary({B1, B2, B3, B4}, Bits) when Bits >= 32->
address_to_binary({B1, B2, B3, B4}, 32) ->
<<B1:8, B2:8, B3:8, B4:8>>;

address_to_binary({B1, B2, B3, B4}, Bits) ->
address_to_binary({B1, B2, B3, B4}, Bits) when Bits < 32 ->
<<Subset:Bits/bitstring, _Others/bitstring>> = <<B1:8, B2:8, B3:8, B4:8>>,
Subset;

address_to_binary({B1, B2, B3, B4}, Bits) when Bits > 32 ->
% matching the IPv4-mapped IPv6 address
<<Subset:Bits/bitstring, _Others/bitstring>> = <<0:80, 16#FFFF:16, B1:8, B2:8, B3:8, B4:8>>,
Subset;

address_to_binary({W1, W2, W3, W4, W5, W6, W7, W8}, Bits) ->
<<Subset:Bits/bitstring, _Others/bitstring>> = <<W1:16, W2:16, W3:16, W4:16, W5:16, W6:16, W7:16, W8:16>>,
Subset;
Expand Down
4 changes: 2 additions & 2 deletions src/rabbitmq_auth_backend_ip_range.app.src
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
%% -*- erlang -*-
{application, rabbitmq_auth_backend_ip_range,
[{description, "RabbitMQ client authorization based on source IP address"},
{vsn, "0.1.0"},
{vsn, "0.1.1"},
{modules, []},
{registered, []},
{mod, {rabbit_auth_backend_ip_range_app, []}},
{env, [{tag_masks,
[{'ip-private', [<<"192.168.0.0/16">>, <<"::FFFF:192.168.0.0/112">>]}]},
[{'ip-private', [<<"::FFFF:192.168.0.0/112">>]}]},
{default_masks, [<<"::0/0">>]}]},
{applications, [kernel, stdlib]}]}.

0 comments on commit aeb3fd0

Please sign in to comment.