Hello! On Mon, Jan 14, 2019 at 06:02:46PM +0200, Dmitriy M. wrote:
> Возможно, не нашел в документации, но есть ли возможность указать от какого > исходящего (локального) IP будет сделать запрос, если это запрос от mail > модуля? Нет, сейчас mail-модуль bind не умеет. > Речь идет об аналоге proxy_bind из модулей http_proxy/stream_proxy > http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_bind . С их > помощью мы успешно решаем проблему нехватки локальных портов при большом > кол-ве исходящих соединений работая с HTTP. > Хотелось бы найти аналог и в mail модуле, т.к. похоже начинает проявляться > та же проблема нехватки локальных портов на почтовом прокси-сервере с > установленным тут nginx и модулем mail, но как обойти её без создания > дополнительных контейнеров (что бы исходящие IP были разные), пока не > придумал (тюнинги системы выполнены, расширен диапазон разрешенных портов и > пр.). Кажется, в случае mail могут иметь смысл два возможных подхода: явная директива proxy_bind (со статически заданным значением, ибо переменных в mail нет), либо же заголовок ответа от auth-скрипта Auth-Bind (аналогично Auth-Server/Auth-Port, задающих собственно адрес проксирования). Патч, добавляющий директиву proxy_bind: # HG changeset patch # User Maxim Dounin <mdou...@mdounin.ru> # Date 1547495341 -10800 # Mon Jan 14 22:49:01 2019 +0300 # Node ID 271bd1fa164251de128cdc35dc1295ceaaa06a30 # Parent 6d15e452fa2eaf19408e24a0d0fcc3a31344a289 Mail: proxy_bind. diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -13,11 +13,12 @@ typedef struct { - ngx_flag_t enable; - ngx_flag_t pass_error_message; - ngx_flag_t xclient; - size_t buffer_size; - ngx_msec_t timeout; + ngx_flag_t enable; + ngx_flag_t pass_error_message; + ngx_flag_t xclient; + size_t buffer_size; + ngx_msec_t timeout; + ngx_addr_t *local; } ngx_mail_proxy_conf_t; @@ -35,6 +36,8 @@ static void ngx_mail_proxy_close_session static void *ngx_mail_proxy_create_conf(ngx_conf_t *cf); static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child); +static char *ngx_mail_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static ngx_command_t ngx_mail_proxy_commands[] = { @@ -60,6 +63,13 @@ static ngx_command_t ngx_mail_proxy_com offsetof(ngx_mail_proxy_conf_t, timeout), NULL }, + { ngx_string("proxy_bind"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, + ngx_mail_proxy_bind, + NGX_MAIL_SRV_CONF_OFFSET, + 0, + NULL }, + { ngx_string("proxy_pass_error_message"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -118,6 +128,7 @@ ngx_mail_proxy_init(ngx_mail_session_t * s->connection->log->action = "connecting to upstream"; + pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); p = ngx_pcalloc(s->connection->pool, sizeof(ngx_mail_proxy_ctx_t)); @@ -134,6 +145,7 @@ ngx_mail_proxy_init(ngx_mail_session_t * p->upstream.get = ngx_event_get_peer; p->upstream.log = s->connection->log; p->upstream.log_error = NGX_ERROR_ERR; + p->upstream.local = pcf->local; rc = ngx_event_connect_peer(&p->upstream); @@ -150,8 +162,6 @@ ngx_mail_proxy_init(ngx_mail_session_t * s->connection->read->handler = ngx_mail_proxy_block_read; p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler; - pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); - s->proxy->buffer = ngx_create_temp_buf(s->connection->pool, pcf->buffer_size); if (s->proxy->buffer == NULL) { @@ -1104,6 +1114,7 @@ ngx_mail_proxy_create_conf(ngx_conf_t *c pcf->xclient = NGX_CONF_UNSET; pcf->buffer_size = NGX_CONF_UNSET_SIZE; pcf->timeout = NGX_CONF_UNSET_MSEC; + pcf->local = NGX_CONF_UNSET_PTR; return pcf; } @@ -1121,6 +1132,52 @@ ngx_mail_proxy_merge_conf(ngx_conf_t *cf ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, (size_t) ngx_pagesize); ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); + ngx_conf_merge_ptr_value(conf->local, prev->local, NULL); return NGX_CONF_OK; } + + +static char * +ngx_mail_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_mail_proxy_conf_t *pcf = conf; + + ngx_int_t rc; + ngx_str_t *value; + + if (pcf->local != NGX_CONF_UNSET_PTR) { + return "is duplicate"; + } + + value = cf->args->elts; + + if (cf->args->nelts == 2 && ngx_strcmp(value[1].data, "off") == 0) { + pcf->local = NULL; + return NGX_CONF_OK; + } + + pcf->local = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); + if (pcf->local == NULL) { + return NGX_CONF_ERROR; + } + + rc = ngx_parse_addr_port(cf->pool, pcf->local, value[1].data, + value[1].len); + + switch (rc) { + case NGX_OK: + pcf->local->name = value[1]; + break; + + case NGX_DECLINED: + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid address \"%V\"", &value[1]); + /* fall through */ + + default: + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} -- Maxim Dounin http://mdounin.ru/ _______________________________________________ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru