Re: Возможность сделать bind() для исходящих запросов модуля mail
Maxim Dounin
mdounin на mdounin.ru
Пн Янв 14 19:50:56 UTC 2019
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 <mdounin at 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