mirror of
https://github.com/internetee/epp_proxy.git
synced 2025-08-15 12:03:47 +02:00
Add X-Forwarded-For header
This commit is contained in:
parent
ffc5ddaa3c
commit
750cdbd270
5 changed files with 42 additions and 17 deletions
|
@ -28,7 +28,6 @@
|
||||||
{ok, CrlFile} -> CrlFile
|
{ok, CrlFile} -> CrlFile
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_cast/2, handle_call/3, start_link/1]).
|
-export([init/1, handle_cast/2, handle_call/3, start_link/1]).
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
-export([init/1, handle_cast/2, handle_call/3, start_link/1]).
|
-export([init/1, handle_cast/2, handle_call/3, start_link/1]).
|
||||||
-export([code_change/3]).
|
-export([code_change/3]).
|
||||||
|
|
||||||
-export([request/5]).
|
-export([request/6]).
|
||||||
|
|
||||||
-record(state,{socket, length, session_id, common_name, client_cert}).
|
-record(state,{socket, session_id, common_name, client_cert, peer_ip}).
|
||||||
|
|
||||||
init(Socket) ->
|
init(Socket) ->
|
||||||
logger:info("Created a worker process"),
|
logger:info("Created a worker process"),
|
||||||
|
@ -22,18 +22,17 @@ start_link(Socket) ->
|
||||||
gen_server:start_link(?MODULE, Socket, []).
|
gen_server:start_link(?MODULE, Socket, []).
|
||||||
|
|
||||||
handle_cast(serve, State = #state{socket=Socket}) ->
|
handle_cast(serve, State = #state{socket=Socket}) ->
|
||||||
|
%% If certificate is revoked, this will fail right away here.
|
||||||
|
%% mod_epp does exactly the same thing.
|
||||||
{ok, SecureSocket} = ssl:handshake(Socket),
|
{ok, SecureSocket} = ssl:handshake(Socket),
|
||||||
{ok, PeerCert} = ssl:peercert(SecureSocket),
|
NewState = state_from_socket(SecureSocket, State),
|
||||||
{SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT} =
|
{noreply, NewState};
|
||||||
epp_certs:headers_from_cert(PeerCert),
|
|
||||||
|
|
||||||
{noreply, State#state{socket=SecureSocket, common_name=SSL_CLIENT_S_DN_CN,
|
|
||||||
client_cert=SSL_CLIENT_CERT}};
|
|
||||||
handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN,
|
handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN,
|
||||||
client_cert=SSL_CLIENT_CERT,
|
client_cert=SSL_CLIENT_CERT,
|
||||||
session_id=SessionId}) ->
|
session_id=SessionId,
|
||||||
|
peer_ip=PeerIp}) ->
|
||||||
Request = request("hello", SessionId, "", SSL_CLIENT_S_DN_CN,
|
Request = request("hello", SessionId, "", SSL_CLIENT_S_DN_CN,
|
||||||
SSL_CLIENT_CERT),
|
SSL_CLIENT_CERT, PeerIp),
|
||||||
logger:info("Request: ~p~n", [Request]),
|
logger:info("Request: ~p~n", [Request]),
|
||||||
|
|
||||||
{_Status, _StatusCode, _Headers, ClientRef} =
|
{_Status, _StatusCode, _Headers, ClientRef} =
|
||||||
|
@ -49,7 +48,8 @@ handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_
|
||||||
handle_cast(process_command, State = #state{socket=Socket,
|
handle_cast(process_command, State = #state{socket=Socket,
|
||||||
common_name=SSL_CLIENT_S_DN_CN,
|
common_name=SSL_CLIENT_S_DN_CN,
|
||||||
client_cert=SSL_CLIENT_CERT,
|
client_cert=SSL_CLIENT_CERT,
|
||||||
session_id=SessionId}) ->
|
session_id=SessionId,
|
||||||
|
peer_ip=PeerIp}) ->
|
||||||
Length = case read_length(Socket) of
|
Length = case read_length(Socket) of
|
||||||
{ok, Data} ->
|
{ok, Data} ->
|
||||||
Data;
|
Data;
|
||||||
|
@ -69,7 +69,7 @@ handle_cast(process_command, State = #state{socket=Socket,
|
||||||
Command = epp_xml:get_command(XMLRecord),
|
Command = epp_xml:get_command(XMLRecord),
|
||||||
|
|
||||||
Request = request(Command, SessionId, Frame, SSL_CLIENT_S_DN_CN,
|
Request = request(Command, SessionId, Frame, SSL_CLIENT_S_DN_CN,
|
||||||
SSL_CLIENT_CERT),
|
SSL_CLIENT_CERT, PeerIp),
|
||||||
logger:info("Request: ~p~n", [Request]),
|
logger:info("Request: ~p~n", [Request]),
|
||||||
|
|
||||||
{_Status, _StatusCode, _Headers, ClientRef} =
|
{_Status, _StatusCode, _Headers, ClientRef} =
|
||||||
|
@ -119,7 +119,7 @@ read_frame(Socket, FrameLength) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% Map request and return values
|
%% Map request and return values
|
||||||
request(Command, SessionId, RawFrame, CommonName, ClientCert) ->
|
request(Command, SessionId, RawFrame, CommonName, ClientCert, PeerIp) ->
|
||||||
URL = epp_router:route_request(Command),
|
URL = epp_router:route_request(Command),
|
||||||
RequestMethod = epp_router:request_method(Command),
|
RequestMethod = epp_router:request_method(Command),
|
||||||
Cookie = hackney_cookie:setcookie("session", SessionId, []),
|
Cookie = hackney_cookie:setcookie("session", SessionId, []),
|
||||||
|
@ -131,7 +131,8 @@ request(Command, SessionId, RawFrame, CommonName, ClientCert) ->
|
||||||
end,
|
end,
|
||||||
Headers = [{"SSL_CLIENT_CERT", ClientCert},
|
Headers = [{"SSL_CLIENT_CERT", ClientCert},
|
||||||
{"SSL_CLIENT_S_DN_CN", CommonName},
|
{"SSL_CLIENT_S_DN_CN", CommonName},
|
||||||
{"User-Agent", <<"EPP proxy">>}],
|
{"User-Agent", <<"EPP proxy">>},
|
||||||
|
{"X-Forwarded-for", epp_util:readable_ip(PeerIp)}],
|
||||||
#epp_request{url=URL, method=RequestMethod, body=Body, cookies=[Cookie],
|
#epp_request{url=URL, method=RequestMethod, body=Body, cookies=[Cookie],
|
||||||
headers=Headers}.
|
headers=Headers}.
|
||||||
|
|
||||||
|
@ -141,3 +142,14 @@ frame_to_socket(Message, Socket) ->
|
||||||
ByteSize = << Length:32/big >>,
|
ByteSize = << Length:32/big >>,
|
||||||
write_line(Socket, ByteSize),
|
write_line(Socket, ByteSize),
|
||||||
write_line(Socket, Message).
|
write_line(Socket, Message).
|
||||||
|
|
||||||
|
%% Extract state info from socket. Fail if you must.
|
||||||
|
state_from_socket(Socket, State) ->
|
||||||
|
{ok, PeerCert} = ssl:peercert(Socket),
|
||||||
|
{ok, {PeerIp, _PeerPort}} = ssl:peername(Socket),
|
||||||
|
{SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT} =
|
||||||
|
epp_certs:headers_from_cert(PeerCert),
|
||||||
|
NewState = State#state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN,
|
||||||
|
client_cert=SSL_CLIENT_CERT, peer_ip=PeerIp},
|
||||||
|
logger:info("Established connection with: [~p]~n", [NewState]),
|
||||||
|
NewState.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
-export([create_map/1, create_session_id/1, frame_length/1,
|
-export([create_map/1, create_session_id/1, frame_length/1,
|
||||||
frame_length_to_receive/1, frame_length_to_send/1,
|
frame_length_to_receive/1, frame_length_to_send/1,
|
||||||
session_id/1]).
|
session_id/1, readable_ip/1]).
|
||||||
|
|
||||||
-define(OFFSET, 4).
|
-define(OFFSET, 4).
|
||||||
|
|
||||||
|
@ -48,3 +48,13 @@ frame_length(Frame) when is_binary(Frame) ->
|
||||||
frame_length(Frame) when is_list(Frame) ->
|
frame_length(Frame) when is_list(Frame) ->
|
||||||
Bin = unicode:characters_to_binary(Frame),
|
Bin = unicode:characters_to_binary(Frame),
|
||||||
byte_size(Bin).
|
byte_size(Bin).
|
||||||
|
|
||||||
|
%% Pass a tuple of IP address, return a binary for sending over the wire.
|
||||||
|
-spec readable_ip({integer(), integer(), integer(), integer()}) -> binary().
|
||||||
|
readable_ip({FirstOctet, SecondOctet, ThirdOctet, FourthOctet}) ->
|
||||||
|
List = [integer_to_list(FirstOctet), ".",
|
||||||
|
integer_to_list(SecondOctet), ".",
|
||||||
|
integer_to_list(ThirdOctet), ".",
|
||||||
|
integer_to_list(FourthOctet)],
|
||||||
|
Binary = list_to_binary(List),
|
||||||
|
Binary.
|
||||||
|
|
|
@ -37,3 +37,7 @@ frame_length_to_receive_test() ->
|
||||||
frame_length_to_send_test() ->
|
frame_length_to_send_test() ->
|
||||||
?assertEqual(18, epp_util:frame_length_to_send("<epp><command>")),
|
?assertEqual(18, epp_util:frame_length_to_send("<epp><command>")),
|
||||||
?assertEqual(4, epp_util:frame_length_to_send("")).
|
?assertEqual(4, epp_util:frame_length_to_send("")).
|
||||||
|
|
||||||
|
readable_ip_test() ->
|
||||||
|
?assertEqual(<<127,46,0,46,0,46,1>>, epp_util:readable_ip({127,0,0,1})),
|
||||||
|
?assertError(function_clause, epp_util:readable_ip({127,0,0,1,0})).
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
{cacertfile_path, "/opt/shared/ca/certs/ca.crt.pem"},
|
{cacertfile_path, "/opt/shared/ca/certs/ca.crt.pem"},
|
||||||
{certfile_path, "/opt/shared/ca/certs/cert.pem"},
|
{certfile_path, "/opt/shared/ca/certs/cert.pem"},
|
||||||
{keyfile_path, "/opt/shared/ca/certs/key.pem"},
|
{keyfile_path, "/opt/shared/ca/certs/key.pem"},
|
||||||
{crlfile_path, "/opt/shared/ca/certs/key.pem"},]}
|
{crlfile_path, "/opt/shared/ca/certs/key.pem"}]}
|
||||||
].
|
].
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue