## 1. Project Overview & Quickstart (haraka/dkimcore.org)

# dkimcore.org

Open-source repository haraka/dkimcore.org

### Repository Details
- **Repository:** [haraka/dkimcore.org](https://github.com/haraka/dkimcore.org)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (haraka/haraka.github.io)

## File: README.md

# haraka.github.io

## Setup

Install dependencies:

```bash
npm install
```

## Development

```bash
npm run dev
```

## Edge Side Rendering

Can be deployed to Vercel Functions, Netlify Functions, AWS, and most Node-compatible environments.

Look at all the available presets [here](https://v3.nuxtjs.org/guide/deploy/presets).

```bash
npm run build
```

## Static Generation

Use the `generate` command to build your application.

The HTML files will be generated in the .output/public directory and ready to be deployed to any static compatible hosting.

```bash
npm run generate
```

## Preview build

You might want to preview the result of your build locally, to do so, run the following command:

```bash
npm run preview
```

---

For a detailed explanation of how things work, check out [Docus](https://docus.dev).

---

## File: content/6.core/1.Address.md

---
title: Address Object
_path: /core/Address
---

# Address Object

The Address object is an interface to reading email addresses passed in at
SMTP time. As such it parses all the formats in RFC-2821 and 2822, and
supports correctly escaping email addresses.

API
---

* new Address (user, host)

Create a new address object for user@host

* new Address (email)

Creates a new address object by parsing the email address. Will throw an
exception if the address cannot be parsed.

* address.user

Access the local part of the email address

* address.host

Access the domain part of the email adress

* address.format()

Provides the email address in the appropriate `` format. And
deals correctly with the null sender and local names.

* address.toString()

Same as format().

* address.address

Provides the email address in 'user@host' format.

Advanced Usage
--------------

It is possible to mess with the regular expressions used to match addresses
for stricter or less strict matching.

To change the behaviour mess with the following variables:

    var adr = require('./address');
	// Now change one of the following. Note they are RegExp objects NOT strings.
    adr.atom_expr;
	adr.address_literal_expr;
	adr.subdomain_expr;
	adr.domain_expr;
	adr.qtext_expr;
	adr.text_expr;
	// Don't forget to recompile:
	adr.compile_re();

---

## File: content/6.core/2.Body.md

---
title: Body Object
_path: /core/Body
---

# Body Object

This documentation has moved to [haraka/email-message](https://github.com/haraka/email-message#body).

---

## File: content/6.core/3.Config.md

---
title: Config
_path: /core/Config
---

# Config

This documentation has moved to [haraka-config](https://github.com/haraka/haraka-config).

---

## File: content/6.core/4.Connection.md

---
title: Connection Object
_path: /core/Connection
---

# Connection Object

For each connection to Haraka there is one connection object.

API
---

* connection.uuid

A unique UUID for this connection.

* connection.remote - info about the host that is connecting to Haraka.

    * ip   - remote IP address
    * host - reverse DNS of the remote hosts IP
    * is_private - true if the remote IP is from a private (loopback, RFC 1918, link local, etc.) IP address.
    * is_local - true if the remote IP is localhost (loopback, link local)

* connection.local - info about the host that is running Haraka

    * ip - the IP of the Haraka server, as reported by the OS
    * port - the port number handling the connection.
    * host - the rDNS host name of the local IP

* connection.proxy - proxy properties set when a proxy is used (like haproxy)
    * allowed - if the remote IP has proxy permission
    * ip - when proxied, the proxy servers IP address
    * type - currently null or 'haproxy'

* connection.hello
    * verb - Either 'EHLO' or 'HELO' whichever the remote end used
    * host - The hostname given with HELO or EHLO

* connection.notes

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).

* connection.transaction

The current transaction object, valid after MAIL FROM, and destroyed at queue
time, RSET time, or if MAIL FROM was rejected. See the Transaction Object
documentation file.

* connection.relaying

A boolean flag to say whether this connection is allowed to relay mails (i.e.
deliver mails outbound). This is normally set by SMTP AUTH, or sometimes via
an IP address check.

* connection.current\_line

For low level use. Contains the current line sent from the remote end,
verbatim as it was sent. Can be useful in certain botnet detection techniques.

* connection.last\_response

Contains the last SMTP response sent to the client.

* connection.remote\_closed

For low level use.  This value is set when the remote host drops the connection.

* connection.results

Store results of processing in a structured format. See [docs/Results](/core/Results)

---

## File: content/6.core/5.CoreConfig.md

---
title: Core Configuration Files
_path: /core/CoreConfig
---

See [Logging](/core/Logging).

The Haraka core reads some configuration files to determine a few actions:

* smtp.yaml or smtp.json

If either of these files exist then they are loaded first.
This file is designed to use the JSON/YAML file overrides documented in
[Config](/core/Config) to optionally provide the entire configuration in a single file.

* plugins

The list of plugins to load

* smtp.ini

  Keys:

  * listen\_host, port - the host and port to listen on (default: ::0 and 25)
  * listen - (default: [::0]:25) Comma separated IP:Port addresses to listen on
  * inactivity\_time - how long to let clients idle in seconds (default: 300)
  * 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)
  * user - optionally a user to drop privileges to. Can be a string or UID.
  * group - optionally a group to drop privileges to. Can be a string or GID.
  * ignore\_bad\_plugins - If a plugin fails to compile by default Haraka will stop at load time.
    If, however, you wish to continue on without that plugin's facilities, then
    set this config option
  * daemonize - enable this to cause Haraka to fork into the background on start-up (default: 0)
  * daemon\_log\_file - (default: /var/log/haraka.log) where to redirect stdout/stderr when daemonized
  * daemon\_pid\_file - (default: /var/run/haraka.pid) where to write a PID file to
  * spool\_dir - (default: none) directory to create temporary spool files in
  * spool\_after - (default: -1) if message exceeds this size in bytes, then spool the message to disk
    specify -1 to disable spooling completely or 0 to force all messages to be spooled to disk.
  * graceful\_shutdown - (default: false) enable this to wait for sockets on shutdown instead of closing them quickly
  * force_shutdown_timeout - (default: 30) number of seconds to wait for a graceful shutdown

* me

  A name to use for this server. Used in received lines and elsewhere. Setup
  by default to be your hostname.

* connection.ini

  See inline comments in connection.ini for the following settings:

  * haproxy.hosts\_ipv4
  * haproxy.hosts\_ipv6
  * headers.\*
  * max.bytes
  * max.line\_length
  * max.data\_line\_length
  * max.mime\_parts
  * message.greeting
  * message.close
  * smtputf8
  * strict\_rfc1869
  * uuid.deny\_chars
  * uuid.banner\_bytes

* plugin\_timeout

  Seconds to allow a plugin to run before the next hook is called automatically
  default: 30

  Note also that each plugin can have a `config/.timeout`
  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.

  If the plugin is in a sub-directory of plugins, then you must create this file
  in the equivalent path e.g. the queue/smtp_forward would need a timeout file in `config/queue/smtp_forward.timeout`

* outbound.ini

* outbound.bounce\_message

  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.

---

## File: content/6.core/6.CustomReturnCodes.md

---
title: Custom Return Codes
_path: /core/CustomReturnCodes
---

# Custom Return Codes

This content has moved to [haraka-dsn](https://github.com/haraka/haraka-dsn).

---

## File: content/6.core/7.HAProxy.md

---
title: HAProxy PROXY protocol extension support
navigation.title: HAProxy
_path: /core/HAProxy
---

# HAProxy

Haraka natively supports the PROXY protocol [1].

This allows an upstream proxy to pass IP address and port of the client which
Haraka will use instead of the socket IP address (which is of the proxy).
This allows DNSBLs and access control lists to operate on the proxied address.

Support is disabled by default and if HAProxy or other attempts to send a
PROXY command then Haraka will return a DENYSOFTDISCONNECT error.
DENYSOFT is used to prevent configuration errors from rejecting valid mail.

To enable support for PROXY you must create a `haproxy_hosts` configuration
file which should contain a list of IP addresses of the HAProxy hosts
that should be allowed to send the PROXY command. A range of IP
addresses can be specified by it's CIDR network address.

When a host connects to Haraka that matches an IP address present in the
`haproxy_hosts` file - a banner is not sent, instead Haraka waits for the
PROXY command to be sent before proceeding.  The connection will timeout
with `421 PROXY timed out` if the command is not sent within 30 seconds.

NOTE: because Haraka does not send a banner when a listed HAProxy host
connects you must set check-send-proxy to ensure that the service checks
send a PROXY command before they run.

[1] http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt

HAProxy supports the PROXY protocol in version 1.5 or later however there
are patches available to add support for 1.4.

Here is an example listener section for haproxy.cfg:

```
listen smtp :25
        mode tcp
        option tcplog
        option smtpchk
        balance roundrobin
        server smtp1 ip.of.haraka.server1:25 check-send-proxy check inter 10s send-proxy
        server smtp2 ip.of.haraka.server2:25 check-send-proxy check inter 10s send-proxy
        server smtp3 ip.of.haraka.server3:25 check-send-proxy check inter 10s send-proxy
        server smtp4 ip.of.haraka.server4:25 check-send-proxy check inter 10s send-proxy
        server smtp5 ip.of.haraka.server5:25 check-send-proxy check inter 10s send-proxy
```

The important part is `send-proxy` which causes HAProxy to send the PROXY
extension on connection.

When using `option smtpchk` you will see CONNRESET errors reported in the Haraka logs as
smtpchk drops the connection before the HELO response is still being written.
You can use the `option tcp-check` instead to provide a better service check by having
the check wait for the banner, send QUIT and then check the response:

```
    option tcp-check
    tcp-check expect rstring ^220\ 
    tcp-check send QUIT\r\n
    tcp-check expect rstring ^221\ 
```

---

## File: content/6.core/8.Logging_API.md

---
title: Logging API
_path: /core/Logging_API
---

# Logging API

Logging conventions within Haraka

See also
------------------
[https://github.com/haraka/Haraka/pull/119]()

logline will always always be in the form:

```text
[level] [connection uuid] [origin] message
```
where origin is "haraka\_core" or the name of the plugin which
triggered the message, and "connection uuid" is the ID of the
connection associated with the message.

when calling a log method on logger, you should provide the
plugin object and the connection object anywhere in the arguments
to the log method.

```js
logger.logdebug("i like turtles", plugin, connection);
```
will yield, for example,

```text
[DEBUG] [7F1C820F-DC79-4192-9AA6-5307354B20A6] [dnsbl] i like turtles
```

if you call the log method on the connection object, you can
forego the connection as argument:

```js
connection.logdebug("turtles all the way down", plugin);
```

and similarly for the log methods on the plugin object:

```js
plugin.logdebug("he just really likes turtles", connection);
```

failing to provide a connection and/or plugin object will leave
the default values in the log (currently "core" and
"no\_connection").

this is implemented by testing for argument type in
the logger.js log\* method. objects-as-arguments are then sniffed
to try to determine if they're a connection or plugin instance.

---

## File: content/6.core/9.Header.md

---
title: Header Object
_path: /core/Header
---

# Header object

This documentation has moved to [haraka/email-message](https://github.com/haraka/email-message#header).