Haraka 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +4 -0
- package/CONTRIBUTORS.md +5 -5
- package/Changes.md +69 -50
- package/Plugins.md +3 -1
- package/README.md +1 -1
- package/bin/haraka +475 -478
- package/config/outbound.ini +3 -0
- package/connection.js +1072 -1108
- package/docs/Connection.md +29 -30
- package/docs/CoreConfig.md +38 -39
- package/docs/CustomReturnCodes.md +0 -1
- package/docs/HAProxy.md +2 -2
- package/docs/Header.md +1 -1
- package/docs/Logging.md +29 -5
- package/docs/Outbound.md +93 -78
- package/docs/Plugins.md +103 -108
- package/docs/Transaction.md +49 -51
- package/docs/Tutorial.md +127 -143
- package/docs/deprecated/access.md +0 -1
- package/docs/deprecated/backscatterer.md +2 -3
- package/docs/deprecated/connect.rdns_access.md +18 -27
- package/docs/deprecated/data.headers.md +0 -1
- package/docs/deprecated/data.nomsgid.md +1 -2
- package/docs/deprecated/data.noreceived.md +1 -2
- package/docs/deprecated/data.rfc5322_header_checks.md +1 -2
- package/docs/deprecated/dkim_sign.md +13 -17
- package/docs/deprecated/dkim_verify.md +9 -17
- package/docs/deprecated/dnsbl.md +36 -38
- package/docs/deprecated/dnswl.md +41 -43
- package/docs/deprecated/lookup_rdns.strict.md +21 -34
- package/docs/deprecated/mail_from.access.md +17 -25
- package/docs/deprecated/mail_from.blocklist.md +9 -12
- package/docs/deprecated/mail_from.nobounces.md +1 -2
- package/docs/deprecated/rcpt_to.access.md +20 -27
- package/docs/deprecated/rcpt_to.blocklist.md +10 -13
- package/docs/deprecated/rcpt_to.routes.md +0 -1
- package/docs/deprecated/rdns.regexp.md +13 -15
- package/docs/plugins/aliases.md +89 -89
- package/docs/plugins/auth/auth_bridge.md +5 -7
- package/docs/plugins/auth/auth_ldap.md +11 -14
- package/docs/plugins/auth/auth_proxy.md +10 -12
- package/docs/plugins/auth/auth_vpopmaild.md +5 -6
- package/docs/plugins/auth/flat_file.md +4 -4
- package/docs/plugins/block_me.md +3 -3
- package/docs/plugins/data.signatures.md +1 -2
- package/docs/plugins/delay_deny.md +3 -4
- package/docs/plugins/max_unrecognized_commands.md +4 -4
- package/docs/plugins/prevent_credential_leaks.md +6 -6
- package/docs/plugins/process_title.md +18 -18
- package/docs/plugins/queue/deliver.md +2 -3
- package/docs/plugins/queue/discard.md +4 -4
- package/docs/plugins/queue/lmtp.md +1 -3
- package/docs/plugins/queue/qmail-queue.md +7 -9
- package/docs/plugins/queue/quarantine.md +16 -21
- package/docs/plugins/queue/rabbitmq.md +8 -11
- package/docs/plugins/queue/rabbitmq_amqplib.md +43 -39
- package/docs/plugins/queue/smtp_bridge.md +7 -10
- package/docs/plugins/queue/smtp_forward.md +42 -34
- package/docs/plugins/queue/smtp_proxy.md +30 -29
- package/docs/plugins/queue/test.md +1 -3
- package/docs/plugins/rcpt_to.in_host_list.md +6 -6
- package/docs/plugins/rcpt_to.max_count.md +1 -1
- package/docs/plugins/record_envelope_addresses.md +3 -3
- package/docs/plugins/reseed_rng.md +6 -6
- package/docs/plugins/status.md +9 -8
- package/docs/plugins/tarpit.md +7 -11
- package/docs/plugins/tls.md +12 -17
- package/docs/plugins/toobusy.md +4 -4
- package/docs/plugins/xclient.md +3 -3
- package/docs/tutorials/Migrating_from_v1_to_v2.md +19 -41
- package/docs/tutorials/SettingUpOutbound.md +6 -9
- package/endpoint.js +35 -38
- package/eslint.config.mjs +22 -19
- package/haraka.js +42 -47
- package/host_pool.js +75 -79
- package/http/html/404.html +45 -49
- package/http/html/index.html +39 -28
- package/http/package.json +2 -4
- package/line_socket.js +27 -28
- package/logger.js +182 -201
- package/outbound/client_pool.js +34 -27
- package/outbound/config.js +64 -59
- package/outbound/fsync_writestream.js +24 -25
- package/outbound/hmail.js +888 -835
- package/outbound/index.js +194 -187
- package/outbound/qfile.js +49 -52
- package/outbound/queue.js +197 -190
- package/outbound/timer_queue.js +41 -43
- package/outbound/tls.js +68 -61
- package/outbound/todo.js +11 -11
- package/package.json +38 -33
- package/plugins/.eslintrc.yaml +0 -1
- package/plugins/auth/auth_base.js +123 -127
- package/plugins/auth/auth_bridge.js +7 -7
- package/plugins/auth/auth_proxy.js +121 -126
- package/plugins/auth/auth_vpopmaild.js +84 -85
- package/plugins/auth/flat_file.js +18 -17
- package/plugins/block_me.js +31 -31
- package/plugins/data.signatures.js +13 -13
- package/plugins/delay_deny.js +65 -61
- package/plugins/prevent_credential_leaks.js +23 -23
- package/plugins/process_title.js +125 -128
- package/plugins/profile.js +5 -5
- package/plugins/queue/deliver.js +3 -3
- package/plugins/queue/discard.js +13 -14
- package/plugins/queue/lmtp.js +16 -17
- package/plugins/queue/qmail-queue.js +54 -55
- package/plugins/queue/quarantine.js +68 -70
- package/plugins/queue/rabbitmq.js +80 -87
- package/plugins/queue/rabbitmq_amqplib.js +75 -54
- package/plugins/queue/smtp_bridge.js +16 -16
- package/plugins/queue/smtp_forward.js +175 -179
- package/plugins/queue/smtp_proxy.js +69 -71
- package/plugins/queue/test.js +9 -9
- package/plugins/rcpt_to.host_list_base.js +30 -34
- package/plugins/rcpt_to.in_host_list.js +19 -19
- package/plugins/record_envelope_addresses.js +4 -4
- package/plugins/reseed_rng.js +4 -4
- package/plugins/status.js +90 -97
- package/plugins/tarpit.js +25 -14
- package/plugins/tls.js +68 -68
- package/plugins/toobusy.js +21 -23
- package/plugins/xclient.js +51 -53
- package/plugins.js +276 -293
- package/rfc1869.js +30 -35
- package/server.js +308 -299
- package/smtp_client.js +244 -228
- package/test/.eslintrc.yaml +0 -1
- package/test/connection.js +127 -134
- package/test/endpoint.js +53 -47
- package/test/fixtures/line_socket.js +12 -12
- package/test/fixtures/util_hmailitem.js +89 -85
- package/test/host_pool.js +90 -92
- package/test/installation/plugins/base_plugin.js +2 -2
- package/test/installation/plugins/folder_plugin/index.js +2 -3
- package/test/installation/plugins/inherits.js +3 -3
- package/test/installation/plugins/load_first.js +2 -3
- package/test/installation/plugins/plugin.js +1 -3
- package/test/installation/plugins/tls.js +2 -4
- package/test/logger.js +135 -116
- package/test/outbound/hmail.js +49 -35
- package/test/outbound/index.js +118 -101
- package/test/outbound/qfile.js +51 -53
- package/test/outbound_bounce_net_errors.js +84 -69
- package/test/outbound_bounce_rfc3464.js +235 -165
- package/test/plugins/auth/auth_base.js +420 -279
- package/test/plugins/auth/auth_vpopmaild.js +38 -39
- package/test/plugins/queue/smtp_forward.js +126 -104
- package/test/plugins/rcpt_to.host_list_base.js +85 -67
- package/test/plugins/rcpt_to.in_host_list.js +159 -112
- package/test/plugins/status.js +71 -64
- package/test/plugins/tls.js +37 -34
- package/test/plugins.js +97 -92
- package/test/rfc1869.js +19 -26
- package/test/server.js +293 -272
- package/test/smtp_client.js +180 -176
- package/test/tls_socket.js +62 -66
- package/test/transaction.js +159 -160
- package/tls_socket.js +331 -333
- package/transaction.js +129 -137
package/docs/Connection.md
CHANGED
|
@@ -1,67 +1,66 @@
|
|
|
1
|
-
Connection Object
|
|
2
|
-
=================
|
|
1
|
+
# Connection Object
|
|
3
2
|
|
|
4
3
|
For each connection to Haraka there is one connection object.
|
|
5
4
|
|
|
6
|
-
API
|
|
7
|
-
---
|
|
5
|
+
## API
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
- connection.uuid
|
|
10
8
|
|
|
11
9
|
A unique UUID for this connection.
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
- connection.remote - info about the host that is connecting to Haraka.
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
- ip - remote IP address
|
|
14
|
+
- host - reverse DNS of the remote hosts IP
|
|
15
|
+
- is_private - true if the remote IP is from a private (loopback, RFC 1918, link local, etc.) IP address.
|
|
16
|
+
- is_local - true if the remote IP is localhost (loopback, link local)
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
- connection.local - info about the host that is running Haraka
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
- ip - the IP of the Haraka server, as reported by the OS
|
|
21
|
+
- port - the port number handling the connection.
|
|
22
|
+
- host - the rDNS host name of the local IP
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
* allowed - if the remote IP has proxy permission
|
|
28
|
-
* ip - when proxied, the proxy servers IP address
|
|
29
|
-
* type - currently null or 'haproxy'
|
|
24
|
+
- connection.proxy - proxy properties set when a proxy is used (like haproxy)
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
- allowed - if the remote IP has proxy permission
|
|
27
|
+
- ip - when proxied, the proxy servers IP address
|
|
28
|
+
- type - currently null or 'haproxy'
|
|
34
29
|
|
|
35
|
-
|
|
30
|
+
- connection.hello
|
|
31
|
+
|
|
32
|
+
- verb - Either 'EHLO' or 'HELO' whichever the remote end used
|
|
33
|
+
- host - The hostname given with HELO or EHLO
|
|
34
|
+
|
|
35
|
+
- connection.notes
|
|
36
36
|
|
|
37
37
|
An object which persists during the lifetime of the connection. It is used to store connection-specific properties. See also, connection.results and [haraka-notes](https://github.com/haraka/haraka-notes).
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
- connection.transaction
|
|
40
40
|
|
|
41
41
|
The current transaction object, valid after MAIL FROM, and destroyed at queue
|
|
42
42
|
time, RSET time, or if MAIL FROM was rejected. See the Transaction Object
|
|
43
43
|
documentation file.
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
- connection.relaying
|
|
46
46
|
|
|
47
47
|
A boolean flag to say whether this connection is allowed to relay mails (i.e.
|
|
48
48
|
deliver mails outbound). This is normally set by SMTP AUTH, or sometimes via
|
|
49
49
|
an IP address check.
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
- connection.current_line
|
|
52
52
|
|
|
53
53
|
For low level use. Contains the current line sent from the remote end,
|
|
54
54
|
verbatim as it was sent. Can be useful in certain botnet detection techniques.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
- connection.last_response
|
|
57
57
|
|
|
58
58
|
Contains the last SMTP response sent to the client.
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
- connection.remote_closed
|
|
61
61
|
|
|
62
|
-
For low level use.
|
|
62
|
+
For low level use. This value is set when the remote host drops the connection.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
- connection.results
|
|
65
65
|
|
|
66
66
|
Store results of processing in a structured format. See [haraka-results](https://github.com/haraka/haraka-results)
|
|
67
|
-
|
package/docs/CoreConfig.md
CHANGED
|
@@ -1,78 +1,77 @@
|
|
|
1
|
-
Core Configuration Files
|
|
2
|
-
========================
|
|
1
|
+
# Core Configuration Files
|
|
3
2
|
|
|
4
3
|
See [Logging](Logging.md).
|
|
5
4
|
|
|
6
5
|
The Haraka core reads some configuration files to determine a few actions:
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
- smtp.yaml or smtp.json
|
|
9
8
|
|
|
10
9
|
If either of these files exist then they are loaded first.
|
|
11
10
|
This file is designed to use the JSON/YAML file overrides documented in
|
|
12
11
|
[haraka-config](https://github.com/haraka/haraka-config) to optionally provide the entire configuration in a single file.
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
- plugins
|
|
15
14
|
|
|
16
15
|
The list of plugins to load
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
- smtp.ini
|
|
19
18
|
|
|
20
19
|
Keys:
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
- listen_host, port - the host and port to listen on (default: ::0 and 25)
|
|
22
|
+
- listen - (default: [::0]:25) Comma separated IP:Port addresses to listen on
|
|
23
|
+
- inactivity_time - how long to let clients idle in seconds (default: 300)
|
|
24
|
+
- nodes - specifies how many processes to fork. The string "cpus" will fork as many children as there are CPUs (default: 1, which enables cluster mode with a single process)
|
|
25
|
+
- user - optionally a user to drop privileges to. Can be a string or UID.
|
|
26
|
+
- group - optionally a group to drop privileges to. Can be a string or GID.
|
|
27
|
+
- ignore_bad_plugins - If a plugin fails to compile by default Haraka will stop at load time.
|
|
29
28
|
If, however, you wish to continue on without that plugin's facilities, then
|
|
30
29
|
set this config option
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
- daemonize - enable this to cause Haraka to fork into the background on start-up (default: 0)
|
|
31
|
+
- daemon_log_file - (default: /var/log/haraka.log) where to redirect stdout/stderr when daemonized
|
|
32
|
+
- daemon_pid_file - (default: /var/run/haraka.pid) where to write a PID file to
|
|
33
|
+
- spool_dir - (default: none) directory to create temporary spool files in
|
|
34
|
+
- spool_after - (default: -1) if message exceeds this size in bytes, then spool the message to disk
|
|
36
35
|
specify -1 to disable spooling completely or 0 to force all messages to be spooled to disk.
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
- graceful_shutdown - (default: false) enable this to wait for sockets on shutdown instead of closing them quickly
|
|
37
|
+
- force_shutdown_timeout - (default: 30) number of seconds to wait for a graceful shutdown
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
- me
|
|
41
40
|
|
|
42
41
|
A name to use for this server. Used in received lines and elsewhere. Setup
|
|
43
42
|
by default to be your hostname.
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
- connection.ini
|
|
46
45
|
|
|
47
46
|
See inline comments in connection.ini for the following settings:
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
- haproxy.hosts_ipv4
|
|
49
|
+
- haproxy.hosts_ipv6
|
|
50
|
+
- headers.\*
|
|
51
|
+
- max.bytes
|
|
52
|
+
- max.line_length
|
|
53
|
+
- max.data_line_length
|
|
54
|
+
- max.mime_parts
|
|
55
|
+
- message.greeting
|
|
56
|
+
- message.close
|
|
57
|
+
- smtputf8
|
|
58
|
+
- strict_rfc1869
|
|
59
|
+
- uuid.deny_chars
|
|
60
|
+
- uuid.banner_bytes
|
|
61
|
+
|
|
62
|
+
- plugin_timeout
|
|
64
63
|
|
|
65
64
|
Seconds to allow a plugin to run before the next hook is called automatically
|
|
66
65
|
default: 30
|
|
67
66
|
|
|
68
67
|
Note also that each plugin can have a `config/<plugin_name>.timeout`
|
|
69
|
-
file specifying a per-plugin timeout.
|
|
68
|
+
file specifying a per-plugin timeout. In this file you can set a timeout of 0 to mean that this plugin's hooks never time out. Use this with care.
|
|
70
69
|
|
|
71
70
|
If the plugin is in a sub-directory of plugins, then you must create this file
|
|
72
71
|
in the equivalent path e.g. the queue/smtp_forward would need a timeout file in `config/queue/smtp_forward.timeout`
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
- outbound.ini
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
- outbound.bounce_message
|
|
77
76
|
|
|
78
77
|
The bounce message if delivery of the message fails. The default is normally fine. Bounce messages contain a number of template replacement values which are best discovered by looking at the source code.
|
package/docs/HAProxy.md
CHANGED
|
@@ -37,7 +37,7 @@ When using `option smtpchk` you will see CONNRESET errors reported in the Haraka
|
|
|
37
37
|
|
|
38
38
|
```
|
|
39
39
|
option tcp-check
|
|
40
|
-
tcp-check expect rstring ^220\
|
|
40
|
+
tcp-check expect rstring ^220\
|
|
41
41
|
tcp-check send QUIT\r\n
|
|
42
|
-
tcp-check expect rstring ^221\
|
|
42
|
+
tcp-check expect rstring ^221\
|
|
43
43
|
```
|
package/docs/Header.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
moved to [Header](https://github.com/haraka/email-message#header)
|
|
1
|
+
moved to [Header](https://github.com/haraka/email-message#header)
|
package/docs/Logging.md
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Haraka has built-in logging (see API docs below) and support for log plugins.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- log.ini
|
|
6
6
|
|
|
7
7
|
Contains settings for log level, timestamps, and format. See the example log.ini file for examples.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- loglevel
|
|
10
10
|
|
|
11
11
|
The loglevel file provides a finger-friendly way to change the loglevel on the CLI. Use it like so: `echo DEBUG > config/loglevel`. When the level in log.ini is set and the loglevel file is present, the loglevel file wins. During runtime, whichever was edited most recently wins.
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
## Logging API
|
|
15
14
|
|
|
16
15
|
Logging conventions within Haraka
|
|
@@ -61,7 +60,12 @@ Here's an example of a log line generated with `logfmt`:
|
|
|
61
60
|
And the same line formatted as JSON:
|
|
62
61
|
|
|
63
62
|
```json
|
|
64
|
-
{
|
|
63
|
+
{
|
|
64
|
+
"level": "PROTOCOL",
|
|
65
|
+
"uuid": "9FF7F70E-5D57-435A-AAD9-EA069B6159D9.1",
|
|
66
|
+
"source": "core",
|
|
67
|
+
"message": "S: 354 go ahead, make my day"
|
|
68
|
+
}
|
|
65
69
|
```
|
|
66
70
|
|
|
67
71
|
Any objects passed to the log methods will also have their properties included in the log line. For example, using `logfmt`:
|
|
@@ -71,5 +75,25 @@ Any objects passed to the log methods will also have their properties included i
|
|
|
71
75
|
And using JSON:
|
|
72
76
|
|
|
73
77
|
```json
|
|
74
|
-
{
|
|
78
|
+
{
|
|
79
|
+
"level": "NOTICE",
|
|
80
|
+
"uuid": "9FF7F70E-5D57-435A-AAD9-EA069B6159D9.1",
|
|
81
|
+
"source": "core",
|
|
82
|
+
"message": "disconnect",
|
|
83
|
+
"ip": "127.0.0.1",
|
|
84
|
+
"rdns": "Unknown",
|
|
85
|
+
"helo": "3h2dnz8a0if",
|
|
86
|
+
"relay": "N",
|
|
87
|
+
"early": "N",
|
|
88
|
+
"esmtp": "N",
|
|
89
|
+
"tls": "N",
|
|
90
|
+
"pipe": "N",
|
|
91
|
+
"errors": 0,
|
|
92
|
+
"txns": 1,
|
|
93
|
+
"rcpts": "1/0/0",
|
|
94
|
+
"msgs": "1/0/0",
|
|
95
|
+
"bytes": 222,
|
|
96
|
+
"lr": "",
|
|
97
|
+
"time": 0.052
|
|
98
|
+
}
|
|
75
99
|
```
|
package/docs/Outbound.md
CHANGED
|
@@ -12,15 +12,15 @@ To flush the outbound queue (for temporary failed mails) hit the Haraka master p
|
|
|
12
12
|
|
|
13
13
|
### outbound.ini
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
- `disabled`
|
|
16
16
|
|
|
17
17
|
Default: false. Allows one to temporarily disable outbound delivery, while still receiving and queuing emails. This can be changed while Haraka is running.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
- `concurrency_max`
|
|
20
20
|
|
|
21
21
|
Default: 100. Specifies the maximum concurrent connections to make. Note that if using cluster (multiple CPUs) this will be multiplied by the number of CPUs that you have.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
- `enable_tls`
|
|
24
24
|
|
|
25
25
|
Default: true. Switch to false to disable TLS for outbound mail.
|
|
26
26
|
|
|
@@ -33,27 +33,39 @@ Within `tls.ini` you can specify global options for the values `ciphers`, `minVe
|
|
|
33
33
|
ciphers=!DES
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
- `always_split`
|
|
37
37
|
|
|
38
38
|
Default: false. By default, Haraka groups message recipients by domain so that messages with multiple recipients at the same domain get sent in a single SMTP session. When `always_split` is enabled, each recipient gets a queue entry and delivery in its own SMTP session. This carries a performance penalty but enables more flexibility in mail delivery and bounce handling.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
- `received_header`
|
|
41
41
|
|
|
42
|
-
Default: "Haraka outbound". If this text is any string except
|
|
42
|
+
Default: "Haraka outbound". If this text is any string except _disabled_, the string is attached as a `Received` header to all outbound mail just before it is queued.
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
- `connect_timeout`
|
|
45
45
|
|
|
46
46
|
Timeout for connecting to remote servers. Default: 30s
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
- `local_mx_ok`
|
|
49
49
|
|
|
50
50
|
Default: false. By default, outbound to a local IP is disabled, to avoid creating mail loops. Set this to true if you want to allow outbound to local IPs. This could be useful if you want to deliver mail to private IPs or localhost on another port.
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
- `temp_fail_intervals`
|
|
53
53
|
|
|
54
54
|
Set this to specify the delay intervals to use between trying to re-send an email that has a temporary failure condition. The setting is a comma separated list of time spans and multipliers. The time span is a number followed by `s`, `m`, `h`, or `d` to represent seconds, minutes, hours, and days, respectively. The multiplier is an asterisk followed by an integer representing the number of times to repeat the interval. For example, the entry `1m, 5m*2, 1h*3` results in an array of delay times of `[60,300,300,3600,3600,3600]` in seconds. The email will be bounced when the array runs out of intervals (the 7th failure in this case). Set this to `none` to bounce the email on the first temporary failure.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
* `inet_prefer`
|
|
57
|
+
|
|
58
|
+
Default: default. Selects the preferred address family (IP version) to deliver messages.
|
|
59
|
+
|
|
60
|
+
| Value | Description |
|
|
61
|
+
|------------------------|-------------|
|
|
62
|
+
| `default` | Prefer IPv6 when IPv4 and IPv6 IPs exist at the same MX priority |
|
|
63
|
+
| `v4` | Try IPv4 addresses first, then IPv6 |
|
|
64
|
+
| `v6` | Try IPv6 addresses first, then IPv4 |
|
|
65
|
+
|
|
66
|
+
Note: Delivery attempts follow MX priority order. Socket-based deliveries ignore this setting.
|
|
67
|
+
|
|
68
|
+
### outbound.bounce_message
|
|
57
69
|
|
|
58
70
|
See "Bounce Messages" below for details.
|
|
59
71
|
|
|
@@ -65,33 +77,33 @@ You likely won't ever need to call methods on this object, so they are left undo
|
|
|
65
77
|
|
|
66
78
|
The attributes of an `hmail` object that may be of use are:
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
- path - the full path to the queue file
|
|
81
|
+
- filename - the filename within the queue dir
|
|
82
|
+
- num_failures - the number of times this mail has been temp failed
|
|
83
|
+
- notes - notes you can store on a hmail object (similar to `transaction.notes`) to allow you to pass information between outbound hooks
|
|
84
|
+
- todo - see below
|
|
73
85
|
|
|
74
86
|
## The ToDo Object
|
|
75
87
|
|
|
76
88
|
The `todo` object contains information about how to deliver this mail. Keys you may be interested in are:
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
- rcpt_to - an Array of `Address`<sup>[1](#fn1)</sup> objects - the rfc.2821 recipients of this mail
|
|
91
|
+
- mail_from - an Address<sup>[1](#fn1)</sup> object - the rfc.2821 sender of this mail
|
|
92
|
+
- domain - the domain this mail is going to (see `always_split` above)
|
|
93
|
+
- notes - the original transaction.notes for this mail, also contains the following useful keys:
|
|
94
|
+
- outbound_ip - the IP address to bind to (do not set manually, use the `get_mx` hook)
|
|
95
|
+
- outbound_helo - the EHLO domain to use (again, do not set manually)
|
|
96
|
+
- queue_time - the epoch milliseconds time when this mail was queued
|
|
97
|
+
- uuid - the original transaction.uuid
|
|
98
|
+
- force_tls - if true, this mail will be sent over TLS or defer
|
|
87
99
|
|
|
88
100
|
## Outbound Mail Hooks
|
|
89
101
|
|
|
90
|
-
### The
|
|
102
|
+
### The queue_outbound hook
|
|
91
103
|
|
|
92
104
|
The first hook that is called prior to queueing an outbound mail is the `queue_outbound` hook. Only if all these hooks return `CONT` (or if there are no hooks) will the mail be queued for outbound delivery. A return of `OK` will indicate that the mail has been queued in some custom manner for outbound delivery. Any of the `DENY` return codes will cause the message to be appropriately rejected.
|
|
93
105
|
|
|
94
|
-
### The
|
|
106
|
+
### The send_email hook
|
|
95
107
|
|
|
96
108
|
Parameters: `next, hmail`
|
|
97
109
|
|
|
@@ -99,7 +111,7 @@ Called just as the email is about to be sent.
|
|
|
99
111
|
|
|
100
112
|
Respond with `next(DELAY, delay_seconds)` to defer sending the email at this time.
|
|
101
113
|
|
|
102
|
-
### The
|
|
114
|
+
### The get_mx hook
|
|
103
115
|
|
|
104
116
|
Parameters: `next, hmail, domain`
|
|
105
117
|
|
|
@@ -121,11 +133,11 @@ If you want to change the delay, then call `next(DENYSOFT, delay_in_seconds)`. U
|
|
|
121
133
|
|
|
122
134
|
Parameters: `next, hmail, error`
|
|
123
135
|
|
|
124
|
-
If the mail completely bounces then the `bounce` hook is called. This is
|
|
136
|
+
If the mail completely bounces then the `bounce` hook is called. This is _not_ called if the mail is issued a temporary failure (a 4xx error code). The hook parameter is the error message received from the remote end as an `Error` object. The object may also have the following properties:
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
- mx - the MX object that caused the bounce
|
|
139
|
+
- deferred_rcpt - the deferred recipients that eventually bounced
|
|
140
|
+
- bounced_rcpt - the bounced recipients
|
|
129
141
|
|
|
130
142
|
If you do not wish to have a bounce message sent to the originating sender of the email then you can return `OK` from this hook to stop it from sending a bounce message.
|
|
131
143
|
|
|
@@ -137,20 +149,20 @@ Params is a list of: `[host, ip, response, delay, port, mode, ok_recips, secured
|
|
|
137
149
|
|
|
138
150
|
When mails are successfully delivered to the remote end then the `delivered` hook is called. The return codes from this hook have no effect, so it is only useful for logging the fact that a successful delivery occurred.
|
|
139
151
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
- `host` - Hostname of the MX that the message was delivered to,
|
|
153
|
+
- `ip` - IP address of the host that the message was delivered to,
|
|
154
|
+
- `response` - Variable contains the SMTP response text returned by the host that received the message and will typically contain the remote queue ID and
|
|
155
|
+
- `delay` - Time taken between the queue file being created and the message being delivered.
|
|
156
|
+
- `port` - Port number that the message was delivered to.
|
|
157
|
+
- `mode` - Shows whether SMTP or LMTP was used to deliver the mail.
|
|
158
|
+
- `ok_recips` - an `Address`<sup>[1](#fn1)</sup> array containing all of the recipients that were successfully delivered to.
|
|
159
|
+
- `secured` - A boolean denoting if the connection used TLS or not.
|
|
148
160
|
|
|
149
161
|
## Outbound IP address
|
|
150
162
|
|
|
151
163
|
Normally the OS will decide which IP address will be used for outbound connections using the IP routing table.
|
|
152
164
|
|
|
153
|
-
There are instances where you may want to separate outbound traffic on different IP addresses based on sender, domain or some other identifier. To do this, the IP address that you want to use
|
|
165
|
+
There are instances where you may want to separate outbound traffic on different IP addresses based on sender, domain or some other identifier. To do this, the IP address that you want to use _must_ be bound to an interface (or alias) on the local system.
|
|
154
166
|
|
|
155
167
|
As described above, the outbound IP can be set using the `bind` parameter and also the outbound helo for the IP can be set using the `bind_ehlo` parameter returned by the `get_mx` hook.
|
|
156
168
|
|
|
@@ -166,14 +178,14 @@ The contents of the bounce message are configured by a file called `config/outbo
|
|
|
166
178
|
|
|
167
179
|
Optional: Possibility to add HTML code (with optional image) to the bounce message is possible by adding the files `config/outbound.bounce_message_html`. An image can be attached to the mail by using `config/outbound.bounce_message_image`.
|
|
168
180
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
multiple people
|
|
176
|
-
|
|
181
|
+
- pid - the current process id
|
|
182
|
+
- date - the current date when the bounce occurred
|
|
183
|
+
- me - the contents of `config/me`
|
|
184
|
+
- from - the originating sender of the message
|
|
185
|
+
- msgid - a uuid for the mail
|
|
186
|
+
- to - the end recipient of the message, or the first recipient if it was to
|
|
187
|
+
multiple people
|
|
188
|
+
- reason - the text from the remote server indicating why it bounced
|
|
177
189
|
|
|
178
190
|
Following the bounce message itself will be a copy of the entire original message.
|
|
179
191
|
|
|
@@ -184,31 +196,35 @@ Sometimes it is necessary to generate a new mail from within a plugin.
|
|
|
184
196
|
To do that, you can use the `outbound` module directly:
|
|
185
197
|
|
|
186
198
|
```js
|
|
187
|
-
const outbound = require('./outbound')
|
|
199
|
+
const outbound = require('./outbound')
|
|
188
200
|
|
|
189
|
-
const to = 'user@example.com'
|
|
190
|
-
const from = 'sender@example.com'
|
|
201
|
+
const to = 'user@example.com'
|
|
202
|
+
const from = 'sender@example.com'
|
|
191
203
|
|
|
192
204
|
const contents = [
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
205
|
+
'From: ' + from,
|
|
206
|
+
'To: ' + to,
|
|
207
|
+
'MIME-Version: 1.0',
|
|
208
|
+
'Content-type: text/plain; charset=us-ascii',
|
|
209
|
+
'Subject: Some subject here',
|
|
210
|
+
'',
|
|
211
|
+
'Some email body here',
|
|
212
|
+
'',
|
|
213
|
+
].join('\n')
|
|
201
214
|
|
|
202
215
|
const outnext = (code, msg) => {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
switch (code) {
|
|
217
|
+
case DENY:
|
|
218
|
+
this.logerror('Sending mail failed: ' + msg)
|
|
219
|
+
break
|
|
220
|
+
case OK:
|
|
221
|
+
this.loginfo('mail sent')
|
|
222
|
+
next()
|
|
223
|
+
break
|
|
224
|
+
default:
|
|
225
|
+
this.logerror('Unrecognized return code from sending email: ' + msg)
|
|
226
|
+
next()
|
|
227
|
+
}
|
|
212
228
|
}
|
|
213
229
|
|
|
214
230
|
outbound.send_email(from, to, contents, outnext)
|
|
@@ -219,28 +235,27 @@ The callback on `send_email()` is passed `OK` if the mail is successfully queued
|
|
|
219
235
|
The callback parameter may be omitted if you don't need to handle errors should queueing to disk fail e.g:
|
|
220
236
|
|
|
221
237
|
```js
|
|
222
|
-
outbound.send_email(from, to, contents)
|
|
238
|
+
outbound.send_email(from, to, contents)
|
|
223
239
|
```
|
|
224
240
|
|
|
225
241
|
Various options can be passed to `outbound.send_email` like so:
|
|
226
242
|
|
|
227
243
|
```js
|
|
228
|
-
outbound.send_email(from, to, contents, outnext, options)
|
|
244
|
+
outbound.send_email(from, to, contents, outnext, options)
|
|
229
245
|
```
|
|
230
246
|
|
|
231
247
|
Where `options` is a Object that may contain the following keys:
|
|
232
248
|
|
|
233
|
-
| Key/Value | Description
|
|
234
|
-
|
|
235
|
-
| `dot_stuffed: true` | Use this if you are passing your content dot-stuffed (a dot at the start of a line is doubled, like it is in SMTP conversation, see [RFC 2821][url-rfc2821]
|
|
236
|
-
| `notes: { key: value}` | In case you need notes in the new transaction that `send_email()` creates.
|
|
249
|
+
| Key/Value | Description |
|
|
250
|
+
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
251
|
+
| `dot_stuffed: true` | Use this if you are passing your content dot-stuffed (a dot at the start of a line is doubled, like it is in SMTP conversation, see [RFC 2821][url-rfc2821]. |
|
|
252
|
+
| `notes: { key: value}` | In case you need notes in the new transaction that `send_email()` creates. |
|
|
237
253
|
| `remove_msgid: true` | Remove any Message-Id header found in the message. If you are reading a message in from the filesystem and you want to ensure that a generated Message-Id header is used in preference over the original. This is useful if you are releasing mail from a quarantine. |
|
|
238
|
-
| `remove_date: true` | Remove any Date header found in the message. If you are reading a message in from the filesystem and you want to ensure that a generated Date header is used in preference over the original. This is useful if you are releasing mail from a quarantine.
|
|
239
|
-
| `origin: Object` | Adds object as argument to logger.log calls inside outbound.send_email. Useful for tracking which Plugin/Connection/HMailItem object generated email.
|
|
240
|
-
|
|
254
|
+
| `remove_date: true` | Remove any Date header found in the message. If you are reading a message in from the filesystem and you want to ensure that a generated Date header is used in preference over the original. This is useful if you are releasing mail from a quarantine. |
|
|
255
|
+
| `origin: Object` | Adds object as argument to logger.log calls inside outbound.send_email. Useful for tracking which Plugin/Connection/HMailItem object generated email. |
|
|
241
256
|
|
|
242
257
|
```js
|
|
243
|
-
outbound.send_email(from, to, contents, outnext, { notes: transaction.notes })
|
|
258
|
+
outbound.send_email(from, to, contents, outnext, { notes: transaction.notes })
|
|
244
259
|
```
|
|
245
260
|
|
|
246
261
|
<a name="fn1">1</a>: `Address` objects are [address-rfc2821](https://github.com/haraka/node-address-rfc2821) objects.
|