31#define APR_WANT_BYTEFUNC
36module AP_MODULE_DECLARE_DATA remoteip_module;
119static const char v2sig[12] =
"\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A";
120#define MIN_V1_HDR_LEN 15
121#define MIN_V2_HDR_LEN 16
122#define MIN_HDR_LEN MIN_V1_HDR_LEN
126#ifndef INET6_ADDRSTRLEN
127#define INET6_ADDRSTRLEN 46
177 ?
server->proxies_header_name
215 return (*
ipstr ==
'\0');
247 " the subnet /",
s,
" is invalid for ",
268 "RemoteIP: Error parsing IP %s (%pm error) for %s",
269 arg, &rv,
cmd->cmd->name);
318#if !APR_VERSION_AT_LEAST(1,5,0)
319#define apr_sockaddr_is_wildcard sockaddr_is_wildcard
395 "RemoteIPProxyProtocol: previous setting for %s:%hu from virtual "
396 "host {%s:%hu in %s} is being overridden by virtual host "
397 "{%s:%hu in %s}; new setting is '%s'",
400 new->server_hostname,
new->addrs->host_port,
new->defn_name,
401 flag ?
"On" :
"Off");
485 return apr_psprintf(
p,
"ip address '%s' appears to be invalid: %pm",
508 "RemoteIPProxyProtocol: enabled on %s:%hu",
buf,
info->addr->port);
513 "RemoteIPProxyProtocol: disabled on %s:%hu",
buf,
info->addr->port);
532 char *proxy_ips =
NULL;
541 void *internal =
NULL;
554 "RemoteIPProxyProtocol data is missing, but required! Aborting request.");
562 "Using %s as client's IP from PROXY protocol",
r->
useragent_ip);
571 internal = (
void *) 1;
597 internal =
match[
i].internal;
626 *(remote + strlen(remote)) =
',';
642 "RemoteIP: Header %s value of %s cannot be parsed "
647 *(remote + strlen(remote)) =
',';
676 && ((
temp_sa->sa.sin6.sin6_addr.s6_addr[0] & 0xe0) != 0x20))
680 "RemoteIP: Header %s value of %s appears to be "
681 "a private IP or nonsensical. Ignored",
684 *(remote + strlen(remote)) =
',';
745 ?
"Using %s as client's IP by proxies %s"
746 :
"Using %s as client's IP by internal proxies%s",
757 if (
lr->bind_addr &&
lr->bind_addr->port ==
port) {
775 char buf[
sizeof(
hdr->v1.line)];
780#define GET_NEXT_WORD(field) \
781 word = apr_strtok(NULL, " ", &saveptr); \
783 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03497) \
784 "RemoteIPProxyProtocol: no " field " found in header '%s'", \
790 if (!
end ||
end[1] !=
'\n') {
819 "RemoteIPProxyProtocol: Unable to parse v6 address - APR is not compiled with IPv6 support");
825 "RemoteIPProxyProtocol: unknown family '%s' in header '%s'",
835 "RemoteIPProxyProtocol: invalid client-address '%s' found in "
836 "header '%s'",
word,
hdr->v1.line);
849 "RemoteIPProxyProtocol: error parsing port '%s' in header '%s'",
863 "RemoteIPProxyProtocol: error converting family '%d', host '%s',"
864 " and port '%hu' to sockaddr; header was '%s'",
884 if (
c->master !=
NULL) {
923 "RemoteIPProxyProtocol: enabled on connection to %s:%hu",
924 c->local_ip,
c->local_addr->port);
950 switch (
hdr->v2.ver_cmd & 0xF) {
952 switch (
hdr->v2.fam) {
961 "RemoteIPPProxyProtocol: error creating sockaddr");
965 conn_conf->client_addr->sa.sin.sin_addr.s_addr =
966 hdr->v2.addr.ip4.src_addr;
978 "RemoteIPProxyProtocol: error creating sockaddr");
982 hdr->v2.addr.ip6.src_addr, 16);
986 "RemoteIPProxyProtocol: APR is not compiled with IPv6 support");
992 "RemoteIPProxyProtocol: unsupported protocol %.2hx",
993 (
unsigned short)
hdr->v2.fam);
1000 "RemoteIPProxyProtocol: unsupported command %.2hx",
1001 (
unsigned short)
hdr->v2.ver_cmd);
1010 "RemoteIPProxyProtocol: error converting address to string");
1032 (
hdr->v2.ver_cmd & 0xF0) == 0x20) {
1035 else if (
memcmp(
hdr->v1.line,
"PROXY ", 6) == 0) {
1060 if (
f->c->aborted) {
1086 while (!
ctx->done) {
1093 "failed reading input");
1100 "RemoteIPProxyProtocol header too long, "
1128 if (
ctx->version == 0) {
1132 if (
ctx->version < 0) {
1135 else if (
ctx->version == 1) {
1139 else if (
ctx->version == 2) {
1144 else if (
ctx->version == 1) {
1149 else if (
ctx->version == 2) {
1155 "RemoteIPProxyProtocol protocol header length too long");
1161 if (
ctx->rcvd >=
ctx->need) {
1168 "RemoteIPProxyProtocol: internal error: unknown version "
1169 "%d",
ctx->version);
1193 "RemoteIPProxyProtocol: received valid PROXY header: %s:%hu",
1198 "RemoteIPProxyProtocol: internal error: have data left over; "
1200 ", brigade-empty=%d",
ctx->need,
ctx->rcvd,
1218 "Specifies a request header to trust as the client IP, "
1219 "e.g. X-Forwarded-For"),
1222 "Specifies a request header to record proxy IP's, "
1223 "e.g. X-Forwarded-By; if not given then do not record"),
1225 "Specifies one or more proxies which are trusted "
1226 "to present IP headers"),
1228 "Specifies one or more internal (transparent) proxies "
1229 "which are trusted to present IP headers"),
1232 "The filename to read the list of trusted proxies, "
1233 "see the RemoteIPTrustedProxy directive"),
1236 "The filename to read the list of internal proxies, "
1237 "see the RemoteIPInternalProxy directive"),
1239 RSRC_CONF,
"Enable PROXY protocol handling ('on', 'off')"),
1242 "protocol handling for this list of networks in CIDR format"),
Symbol export macros and hook functions.
Apache Listeners Library.
int int const char ** match
const char apr_size_t len
APR general purpose library routines.
apr_size_t const unsigned char unsigned int unsigned int d
APR Versioning Interface.
APR Standard Headers Support.
void ap_hook_pre_connection(ap_HOOK_pre_connection_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
static apr_pool_t * pconf
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
#define AP_INIT_TAKE_ARGV(directive, func, mconfig, where, help)
int ap_cfg_closefile(ap_configfile_t *cfp)
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
apr_status_t ap_pcfg_openfile(ap_configfile_t **ret_cfg, apr_pool_t *p, const char *name)
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
#define AP_INIT_ITERATE(directive, func, mconfig, where, help)
char * ap_server_root_relative(apr_pool_t *p, const char *fname)
#define ap_set_module_config(v, m, val)
apr_status_t ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp)
ap_filter_t * ap_add_input_filter_handle(ap_filter_rec_t *f, void *ctx, request_rec *r, conn_rec *c)
apr_status_t ap_filter_rec_t * ap_register_input_filter(const char *name, ap_in_filter_func filter_func, ap_init_filter_func filter_init, ap_filter_type ftype)
apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
ap_listen_rec * ap_listeners
server_rec * ap_server_conf
const unsigned char * buf
void ap_hook_post_read_request(ap_HOOK_post_read_request_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
const char apr_port_t port
#define APR_STATUS_IS_EINVAL(s)
#define APR_STATUS_IS_EAGAIN(s)
#define APR_BRIGADE_EMPTY(b)
#define apr_bucket_delete(e)
apr_brigade_flush void * ctx
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
apr_dbd_transaction_t int mode
apr_memcache_server_t * server
#define STANDARD20_MODULE_STUFF
#define ap_strchr_c(s, c)
char * ap_getword_conf(apr_pool_t *p, const char **line)
const apr_array_header_t * list
const char apr_int32_t flag
void * memchr(const void *s, int c, size_t n)
apr_vformatter_buff_t * c
const apr_sockaddr_t * addr2
#define apr_pcalloc(p, size)
apr_size_t const char * filename
const char const char *const * args
Apache connection library.
static ap_filter_rec_t * remoteip_filter
static apr_size_t remoteip_get_v2_len(proxy_header *hdr)
static const char v2sig[12]
static int remoteip_determine_version(conn_rec *c, const char *ptr)
static void * merge_remoteip_server_config(apr_pool_t *p, void *globalv, void *serverv)
static int remoteip_modify_request(request_rec *r)
static const char * remoteip_disable_networks(cmd_parms *cmd, void *d, int argc, char *const argv[])
static remoteip_parse_status_t remoteip_process_v1_header(conn_rec *c, remoteip_conn_config_t *conn_conf, proxy_header *hdr, apr_size_t len, apr_size_t *hdr_len)
static const char * header_name_set(cmd_parms *cmd, void *dummy, const char *arg)
static const command_rec remoteip_cmds[]
static apr_status_t remoteip_input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
static const char * proxies_header_name_set(cmd_parms *cmd, void *dummy, const char *arg)
static int remoteip_hook_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static int remoteip_sockaddr_equal(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
static int remoteip_hook_pre_connection(conn_rec *c, void *csd)
static void register_hooks(apr_pool_t *p)
static const char * remoteip_enable_proxy_protocol(cmd_parms *cmd, void *config, int flag)
static int remoteip_sockaddr_compat(apr_sockaddr_t *addr1, apr_sockaddr_t *addr2)
static int remoteip_is_server_port(apr_port_t port)
static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, remoteip_conn_config_t *conn_conf, proxy_header *hdr)
static void * create_remoteip_server_config(apr_pool_t *p, server_rec *s)
static const char * proxies_set(cmd_parms *cmd, void *cfg, const char *arg)
#define GET_NEXT_WORD(field)
static const char * proxylist_read(cmd_parms *cmd, void *cfg, const char *filename)
static int looks_like_ip(const char *ipstr)
static int remoteip_addr_in_list(remoteip_addr_info *list, apr_sockaddr_t *addr)
static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec *new, int flag)
This structure is used for recording information about the registered filters. It associates a name w...
The representation of a filter chain.
Apache's listeners record.
Structure to store things which are per connection.
struct ap_conf_vector_t * conn_config
struct remoteip_addr_info * next
apr_array_header_t * disabled_subnets
apr_array_header_t * proxymatch_ip
remoteip_addr_info * proxy_protocol_enabled
const char * proxies_header_name
remoteip_addr_info * proxy_protocol_disabled
apr_sockaddr_t * client_addr
const char * proxied_remote
apr_sockaddr_t * useragent_addr
A structure that represents the current request.
apr_sockaddr_t * useragent_addr
A structure to be used for Per-vhost config.
A structure to store information for each virtual server.
struct ap_conf_vector_t * module_config
ap_input_mode_t
input filtering modes