add config option socket, rework example config and release 1.0.0

This commit is contained in:
2020-04-22 23:02:05 +02:00
parent 2d73d525b8
commit 01b516ce7c
6 changed files with 51 additions and 44 deletions

View File

@@ -10,22 +10,21 @@ Pymodmilter is depending on these python packages, but they are installed automa
* [netaddr](https://github.com/drkjam/netaddr/) * [netaddr](https://github.com/drkjam/netaddr/)
## Installation ## Installation
* Install pymodmilter with pip. * Install pymodmilter with pip and copy the example configuration file.
```sh ```sh
pip install pymodmilter pip install pymodmilter
```
* Copy the example configuration file.
```sh
cp /usr/share/doc/pymodmilter/pymodmilter.conf.example /etc/pymodmilter.conf cp /usr/share/doc/pymodmilter/pymodmilter.conf.example /etc/pymodmilter.conf
``` ```
* Modify /etc/pymodmilter.conf according to your needs and you are ready to go. * Modify /etc/pymodmilter.conf according to your needs.
## Configuration options ## Configuration options
Pymodmilter uses a configuration file in JSON format. The options are described below. Make a copy of the [example configuration file](https://github.com/spacefreak86/pymodmilter/blob/master/docs/pymodmilter.conf.example) in the [docs](https://github.com/spacefreak86/pymodmilter/tree/master/docs) folder to start with. Pymodmilter uses a configuration file in JSON format. The options are described below. Make a copy of the [example configuration file](https://github.com/spacefreak86/pymodmilter/blob/master/docs/pymodmilter.conf.example) in the [docs](https://github.com/spacefreak86/pymodmilter/tree/master/docs) folder to start with.
Rules and modifications are processed in the given order. Rules and modifications are processed in the given order.
### Global ### Global
The following optional global configuration options are available: The following global configuration options are optional:
* **socket**
The socket used to communicate with the MTA.
* **local_addrs** * **local_addrs**
A list of hosts and network addresses which are considered local. It is used to for the condition option [local](#Conditions). This option may be overriden within a rule object. A list of hosts and network addresses which are considered local. It is used to for the condition option [local](#Conditions). This option may be overriden within a rule object.
* **log** * **log**

View File

@@ -7,97 +7,106 @@
# #
{ {
# Section: global # Section: global
# Notes: Set default options. # Notes: Global options.
# #
"global": { "global": {
# Option: socket
# Type: String
# Notes: The socket used to communicate with the MTA.
#
# Examples:
# unix:/path/to/socket a named pipe
# inet:8899 listen on ANY interface
# inet:8899@localhost listen on a specific interface
# inet6:8899 listen on ANY interface
# inet6:8899@[2001:db8:1234::1] listen on a specific interface
# Value: [ SOCKET ]
"socket": "inet:8898@127.0.0.1",
# Option: local_addrs # Option: local_addrs
# Type: List # Type: List
# Notes: Set a list of local hosts and networks. # Notes: A list of local hosts and networks.
# Value: [ LIST ] # Value: [ LIST ]
# #
"local_addrs": ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"], "local_addrs": ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
# Option: log # Option: log
# Type: Bool # Type: Bool
# Notes: Set if processing of rules and modifications is logged. # Notes: Enable or disable logging of rules and modifications.
# Value: [ true | false ] # Value: [ true | false ]
# #
"log": true "log": true
}, },
# Section: rules # Section: rules
# Notes: Set rules and related modifications. # Notes: Rules and related modifications.
# #
"rules": [ "rules": [
{ {
# Option: name # Option: name
# Type: String # Type: String
# Notes: Set the name of the rule. # Notes: Name of the rule.
# Value: [ NAME ] # Value: [ NAME ]
# #
"name": "MyRule", "name": "MyRule",
# Section: conditions # Section: conditions
# Notes: Optionally set conditions to run the rule. # Notes: Optional conditions to process the rule.
# If multiple conditions are specified, they all # If multiple conditions are set, they all
# have to be true to run the rule. # have to be true to process the rule.
# #
"conditions": { "conditions": {
# Option: local # Option: local
# Type: Bool # Type: Bool
# Notes: Set a condition on the senders host address. # Notes: Condition wheter the senders host address is listed in local_addrs.
# Set to true to execute the rule only for emails originating
# from addresses defined in local_addrs and vice versa.
# Value: [ true | false ] # Value: [ true | false ]
# #
"local": false, "local": false,
# Option: hosts # Option: hosts
# Type: String # Type: String
# Notes: Set a condition on the senders host address. # Notes: Condition wheter the senders host address is listed in this list.
# The rule will only be executed if the list contains the
# senders host address.
# Value: [ LIST ] # Value: [ LIST ]
# #
"hosts": [ "127.0.0.1" ], "hosts": [ "127.0.0.1" ],
# Option: envfrom # Option: envfrom
# Type: String # Type: String
# Notes: Set a regular expression to match against the envelope-from address. # Notes: Condition wheter the envelop-from address matches this regular expression.
# Value: [ REGEX ] # Value: [ REGEX ]
# #
"envfrom": "^(?!.+@mycompany\\.com).+$" "envfrom": "^(?!.+@mycompany\\.com).+$"
}, },
# Section: modifications # Section: modifications
# Notes: Set modifications for the rule. # Notes: Modifications of the rule.
# #
"modifications": [ "modifications": [
{ {
# Option: name # Option: name
# Type: String # Type: String
# Notes: Set the name of the modification. # Notes: Name of the modification.
# Value: [ NAME ] # Value: [ NAME ]
# #
"name": "AddHeader", "name": "AddHeader",
# Option: type # Option: type
# Type: String # Type: String
# Notes: Set the modification type. # Notes: Type of the modification.
# Value: [ add_header | del_header | mod_header ] # Value: [ add_header | del_header | mod_header ]
# #
"type": "add_header", "type": "add_header",
# Option: header # Option: header
# Type: String # Type: String
# Notes: Set the name of the new header. # Notes: Name of the header.
# Value: [ NAME ] # Value: [ NAME ]
# #
"header": "X-Test-Header", "header": "X-Test-Header",
# Option: value # Option: value
# Type: String # Type: String
# Notes: Set the value of the new header. # Notes: Value of the header.
# Value: [ VALUE ] # Value: [ VALUE ]
# #
"value": "true" "value": "true"
@@ -108,21 +117,21 @@
# Option: header # Option: header
# Type: String # Type: String
# Notes: Set a regular expression to match against header lines (e.g. Subject: Test-Subject). # Notes: Regular expression to match against header lines (e.g. Subject: Test-Subject).
# Value: [ REGEX ] # Value: [ REGEX ]
# #
"header": "^Subject:", "header": "^Subject:",
# Option: search # Option: search
# Type: String # Type: String
# Notes: Set a regular expression to match against the headers value. # Notes: Regular expression to match against the headers value.
# Values: [ VALUE ] # Values: [ VALUE ]
# #
"search": "(?P<subject>.*)", "search": "(?P<subject>.*)",
# Option: value # Option: value
# Type: String # Type: String
# Notes: Set the value of the header. # Notes: New value of the header.
# Values: [ VALUE ] # Values: [ VALUE ]
"value": "[EXTERNAL] \\g<subject>" "value": "[EXTERNAL] \\g<subject>"
}, { }, {
@@ -132,7 +141,7 @@
# Option: header # Option: header
# Type: String # Type: String
# Notes: Set a regular expression to match against header lines (e.g. Subject: Test-Subject). # Notes: Regular expression to match against header lines (e.g. Subject: Test-Subject).
# Value: [ REGEX ] # Value: [ REGEX ]
# #
"header": "^Received:" "header": "^Received:"

View File

@@ -1,14 +1,5 @@
# /etc/conf.d/pymodmilter: config file for /etc/init.d/pymodmilter # /etc/conf.d/pymodmilter: config file for /etc/init.d/pymodmilter
# Set the socket used to communicate with the MTA.
# Examples:
# unix:/path/to/socket a named pipe
# inet:8899 listen on ANY interface
# inet:8899@localhost listen on a specific interface
# inet6:8899 listen on ANY interface
# inet6:8899@[2001:db8:1234::1] listen on a specific interface
SOCKET="inet:8898@127.0.0.1"
# Start the daemon as the user. You can optionally append a group name here also. # Start the daemon as the user. You can optionally append a group name here also.
# USER="daemon" # USER="daemon"
# USER="daemon:nobody" # USER="daemon:nobody"

View File

@@ -1,12 +1,11 @@
#!/sbin/openrc-run #!/sbin/openrc-run
user=${USER:-daemon} user=${USER:-daemon}
socket="${SOCKET:-}"
milter_opts="${MILTER_OPTS:-}" milter_opts="${MILTER_OPTS:-}"
pidfile="/run/${RC_SVCNAME}.pid" pidfile="/run/${RC_SVCNAME}.pid"
command="/usr/bin/pymodmilter" command="/usr/bin/pymodmilter"
command_args="-s ${socket} ${milter_opts}" command_args="${milter_opts}"
command_background=true command_background=true
start_stop_daemon_args="--user ${user}" start_stop_daemon_args="--user ${user}"

View File

@@ -40,7 +40,7 @@ def main():
"-s", "-s",
"--socket", "--socket",
help="Socket used to communicate with the MTA.", help="Socket used to communicate with the MTA.",
required=True) default="")
parser.add_argument( parser.add_argument(
"-d", "-d",
"--debug", "--debug",
@@ -95,6 +95,15 @@ def main():
if "global" not in config: if "global" not in config:
config["global"] = {} config["global"] = {}
if args.socket:
socket = args.socket
elif "socket" in config["global"]:
socket = config["global"]["socket"]
else:
raise RuntimeError(
f"listening socket is neither specified on the command line "
f"nor in the configuration file")
if "local_addrs" not in config["global"]: if "local_addrs" not in config["global"]:
config["global"]["local_addrs"] = [ config["global"]["local_addrs"] = [
"127.0.0.0/8", "127.0.0.0/8",
@@ -177,7 +186,7 @@ def main():
rc = 0 rc = 0
try: try:
Milter.runmilter("pymodmilter", socketname=args.socket, timeout=30) Milter.runmilter("pymodmilter", socketname=socket, timeout=30)
except Milter.milter.error as e: except Milter.milter.error as e:
logger.error(e) logger.error(e)
rc = 255 rc = 255

View File

@@ -1 +1 @@
__version__ = "0.0.9" __version__ = "1.0.0"