Proxy support
There is built-in support for PROXY
since release 3.2.2
. Find more about proxy extension from PROXY protocol.
The extension is disabled by default. You may initialize your server class like:
server = MySmtpd.new(ports: 2525, hosts: '127.0.0.1', proxy_extension: true)
If you have enabled proxy support you may provide your own proxy event method to check access to your server. The default event method will allow all proxy connections per default.
Your own server class may implement the on_proxy_event
:
# check the proxy connection
# if a value is returned, that will be used and stored as proxy information
def on_proxy_event(ctx, proxy_data)
# if necessary you may change the remote ip and port information
ctx[:server][:remote_ip] = proxy_data[:source_ip]
ctx[:server][:remote_host] = proxy_data[:source_ip]
ctx[:server][:remote_port] = proxy_data[:source_port]
proxy_data
end
Instead changing the remote_ip
and other ctx[:server]
vars, you will always have access to the server context proxy data ctx[:server][:proxy]
.
def other_event(ctx)
if ctx[:server][:proxy]
puts "This is the client IP: #{ctx[:server][:proxy][:source_ip]"
end
end
Rules for Proxy support
proxy_extension = false (DEFAULT)
- PROXY commands are ignored and could be catch in a individual method using the
on_process_line_unknown_event
proxy_extension = true
- Only valid PROXY protocol v1 commands are allowed
- All invalid PROXY commands causes immediately a drop and close of the connection (Code 421)
- PROXY command is in general optional and not mandatory even when extension is enabled
- Strict checking of values on processing like tcp4/6 addresses and port ranges
- Only ONE PROXY LINE is allowed - check the
accept-proxy
directive if having issues - At the
on_proxy_event
you may check the connection data and grant or disallow access. - If a
PROXY
command is used later while already in a session it just raises an invalid sequence error
Resolv client ip address as hostname (DNS)
If you need for some reason the client hostname you may use the builtin library resolv
for that job. Checkout the ruby documentation at Resolv.
A simple implementation looks like:
# require the builtin library
require 'resolv'
def on_proxy_event(ctx, proxy_data)
# update the proxy data
begin
proxy_data[:source_host] = Resolv.getname(proxy_data[:source_ip])
rescue NameError
end
# rewrite the remote connection information
ctx[:server][:remote_ip] = proxy_data[:source_ip]
ctx[:server][:remote_host] = proxy_data[:source_host]
ctx[:server][:remote_port] = proxy_data[:source_port]
# return the values to store as proxy data
proxy_data
end