Maxim Dounin
January 15, 2019 08:44AM
Hello!

On Tue, Jan 15, 2019 at 01:28:52PM +0200, Dmitriy M. wrote:

> Спасибо за развернутый ответ и патч.
>
> Мы модифицировали патч, добавив логику перебора IP исходящих соединений. В
> нашем случае нам достаточно 4х IP, т.е.:
>
> proxy_bind 10.10.0.1 10.10.0.2 10.10.0.3 10.10.0.4;
>
> Вроде работает пока, балансируя соединения с 4 IP поровну.

Нет, так мы точно делать не будем. Если хочется вращать много
локальных адресов в рамках одного сервера - то вот патч, который
позволяет задать локальный адрес из auth-скрипта с помощью
заголовка Auth-Bind:

# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1547559561 -10800
# Tue Jan 15 16:39:21 2019 +0300
# Node ID 7d052f39bf8c8fb028569e290f67edf4bacb3252
# Parent 6d15e452fa2eaf19408e24a0d0fcc3a31344a289
Mail: Auth-Bind header.

diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h
--- a/src/mail/ngx_mail.h
+++ b/src/mail/ngx_mail.h
@@ -400,7 +400,8 @@ char *ngx_mail_capabilities(ngx_conf_t *


/* STUB */
-void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer);
+void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer,
+ ngx_addr_t *local);
void ngx_mail_auth_http_init(ngx_mail_session_t *s);
/**/

diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -53,6 +53,7 @@ struct ngx_mail_auth_http_ctx_s {
ngx_str_t err;
ngx_str_t errmsg;
ngx_str_t errcode;
+ ngx_str_t bind;

time_t sleep;

@@ -467,7 +468,7 @@ ngx_mail_auth_http_process_headers(ngx_m
time_t timer;
size_t len, size;
ngx_int_t rc, port, n;
- ngx_addr_t *peer;
+ ngx_addr_t *peer, *local;

ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http process headers");
@@ -677,6 +678,18 @@ ngx_mail_auth_http_process_headers(ngx_m
continue;
}

+ if (len == sizeof("Auth-Bind") - 1
+ && ngx_strncasecmp(ctx->header_name_start,
+ (u_char *) "Auth-Bind",
+ sizeof("Auth-Bind") - 1)
+ == 0)
+ {
+ ctx->bind.len = ctx->header_end - ctx->header_start;
+ ctx->bind.data = ctx->header_start;
+
+ continue;
+ }
+
/* ignore other headers */

continue;
@@ -772,6 +785,52 @@ ngx_mail_auth_http_process_headers(ngx_m
return;
}

+ if (ctx->bind.len) {
+
+ local = ngx_palloc(s->connection->pool, sizeof(ngx_addr_t));
+ if (local == NULL) {
+ ngx_close_connection(ctx->peer.connection);
+ ngx_destroy_pool(ctx->pool);
+ ngx_mail_session_internal_server_error(s);
+ return;
+ }
+
+ rc = ngx_parse_addr_port(s->connection->pool, local,
+ ctx->bind.data, ctx->bind.len);
+
+ switch (rc) {
+ case NGX_OK:
+ break;
+
+ case NGX_DECLINED:
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "auth http server %V sent invalid bind "
+ "address:\"%V\"",
+ ctx->peer.name, &ctx->bind);
+ /* fall through */
+
+ default:
+ ngx_destroy_pool(ctx->pool);
+ ngx_mail_session_internal_server_error(s);
+ return;
+ }
+
+ local->name.len = ctx->bind.len;
+
+ local->name.data = ngx_pnalloc(s->connection->pool,
+ local->name.len);
+ if (local->name.data == NULL) {
+ ngx_destroy_pool(ctx->pool);
+ ngx_mail_session_internal_server_error(s);
+ return;
+ }
+
+ ngx_memcpy(local->name.data, ctx->bind.data, ctx->bind.len);
+
+ } else {
+ local = NULL;
+ }
+
peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_addr_t));
if (peer == NULL) {
ngx_destroy_pool(ctx->pool);
@@ -832,7 +891,7 @@ ngx_mail_auth_http_process_headers(ngx_m
ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);

ngx_destroy_pool(ctx->pool);
- ngx_mail_proxy_init(s, peer);
+ ngx_mail_proxy_init(s, peer, local);

return;
}
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
@@ -109,7 +109,7 @@ static u_char smtp_auth_ok[] = "235 2.0


void
-ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
+ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer, ngx_addr_t *local)
{
ngx_int_t rc;
ngx_mail_proxy_ctx_t *p;
@@ -134,6 +134,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 = local;

rc = ngx_event_connect_peer(&p->upstream);


--
Maxim Dounin
http://mdounin.ru/
_______________________________________________
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru
Subject Author Posted

Возможность сделать bind() для исходящих запросов модуля mail

Dmitriy M. January 14, 2019 11:04AM

Re: Возможность сделать bind() для исходящих запросов модуля mail

Maxim Dounin January 14, 2019 02:52PM

Re: Возможность сделать bind() для исходящих запросов модуля mail

Dmitriy M. January 15, 2019 06:30AM

Re: Возможность сделать bind() для исходящих запросов модуля mail

Maxim Dounin January 15, 2019 08:44AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 318
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready