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
|
||||
end).
|
||||
|
||||
|
||||
%% gen_server callbacks
|
||||
-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([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) ->
|
||||
logger:info("Created a worker process"),
|
||||
|
@ -22,18 +22,17 @@ start_link(Socket) ->
|
|||
gen_server:start_link(?MODULE, 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, PeerCert} = ssl:peercert(SecureSocket),
|
||||
{SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT} =
|
||||
epp_certs:headers_from_cert(PeerCert),
|
||||
|
||||
{noreply, State#state{socket=SecureSocket, common_name=SSL_CLIENT_S_DN_CN,
|
||||
client_cert=SSL_CLIENT_CERT}};
|
||||
NewState = state_from_socket(SecureSocket, State),
|
||||
{noreply, NewState};
|
||||
handle_cast(greeting, State = #state{socket=Socket, common_name=SSL_CLIENT_S_DN_CN,
|
||||
client_cert=SSL_CLIENT_CERT,
|
||||
session_id=SessionId}) ->
|
||||
session_id=SessionId,
|
||||
peer_ip=PeerIp}) ->
|
||||
Request = request("hello", SessionId, "", SSL_CLIENT_S_DN_CN,
|
||||
SSL_CLIENT_CERT),
|
||||
SSL_CLIENT_CERT, PeerIp),
|
||||
logger:info("Request: ~p~n", [Request]),
|
||||
|
||||
{_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,
|
||||
common_name=SSL_CLIENT_S_DN_CN,
|
||||
client_cert=SSL_CLIENT_CERT,
|
||||
session_id=SessionId}) ->
|
||||
session_id=SessionId,
|
||||
peer_ip=PeerIp}) ->
|
||||
Length = case read_length(Socket) of
|
||||
{ok, Data} ->
|
||||
Data;
|
||||
|
@ -69,7 +69,7 @@ handle_cast(process_command, State = #state{socket=Socket,
|
|||
Command = epp_xml:get_command(XMLRecord),
|
||||
|
||||
Request = request(Command, SessionId, Frame, SSL_CLIENT_S_DN_CN,
|
||||
SSL_CLIENT_CERT),
|
||||
SSL_CLIENT_CERT, PeerIp),
|
||||
logger:info("Request: ~p~n", [Request]),
|
||||
|
||||
{_Status, _StatusCode, _Headers, ClientRef} =
|
||||
|
@ -119,7 +119,7 @@ read_frame(Socket, FrameLength) ->
|
|||
end.
|
||||
|
||||
%% Map request and return values
|
||||
request(Command, SessionId, RawFrame, CommonName, ClientCert) ->
|
||||
request(Command, SessionId, RawFrame, CommonName, ClientCert, PeerIp) ->
|
||||
URL = epp_router:route_request(Command),
|
||||
RequestMethod = epp_router:request_method(Command),
|
||||
Cookie = hackney_cookie:setcookie("session", SessionId, []),
|
||||
|
@ -131,7 +131,8 @@ request(Command, SessionId, RawFrame, CommonName, ClientCert) ->
|
|||
end,
|
||||
Headers = [{"SSL_CLIENT_CERT", ClientCert},
|
||||
{"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],
|
||||
headers=Headers}.
|
||||
|
||||
|
@ -141,3 +142,14 @@ frame_to_socket(Message, Socket) ->
|
|||
ByteSize = << Length:32/big >>,
|
||||
write_line(Socket, ByteSize),
|
||||
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,
|
||||
frame_length_to_receive/1, frame_length_to_send/1,
|
||||
session_id/1]).
|
||||
session_id/1, readable_ip/1]).
|
||||
|
||||
-define(OFFSET, 4).
|
||||
|
||||
|
@ -48,3 +48,13 @@ frame_length(Frame) when is_binary(Frame) ->
|
|||
frame_length(Frame) when is_list(Frame) ->
|
||||
Bin = unicode:characters_to_binary(Frame),
|
||||
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() ->
|
||||
?assertEqual(18, epp_util:frame_length_to_send("<epp><command>")),
|
||||
?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"},
|
||||
{certfile_path, "/opt/shared/ca/certs/cert.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