smailr 0.3.0 → 0.5.0
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.
- data/README.md +168 -0
- data/bin/smailr +45 -22
- data/contrib/exim4.conf +42 -29
- data/contrib/install.pp +95 -0
- data/lib/smailr/dkim.rb +11 -9
- data/lib/smailr/mailbox.rb +6 -0
- data/lib/smailr/model.rb +4 -5
- data/lib/smailr.rb +61 -3
- data/migrations/004_dkims.rb +3 -2
- data/smailr.yml +9 -0
- metadata +6 -3
data/README.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# Smailr - A Virtual Mail Hosting Management CLI (ALPHA)
|
2
|
+
|
3
|
+
Smailr is a small CLI application, which lets you manage the database for a
|
4
|
+
typical Exim/Dovecot stack.
|
5
|
+
|
6
|
+
Configuration files are provided within the contrib directory, so you should be
|
7
|
+
able to get everything up and running within a couple of minutes.
|
8
|
+
|
9
|
+
Please note, Smailr is still in development!
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install Smailr
|
14
|
+
|
15
|
+
# gem install smailr
|
16
|
+
|
17
|
+
Add a user which will own the mails and is used for the LDA
|
18
|
+
|
19
|
+
# useradd -r -d /srv/mail vmail
|
20
|
+
# mkdir /srv/mail/users
|
21
|
+
# chown -R vmail:vmail /srv/mail
|
22
|
+
|
23
|
+
Install Exim and Dovecot
|
24
|
+
|
25
|
+
# aptitude install exim-daemon-heavy dovecot-imapd dovecot-pop3d
|
26
|
+
|
27
|
+
Install the example Exim and Dovecot configration files on your mailserver.
|
28
|
+
|
29
|
+
# smailr setup
|
30
|
+
*****************************************************************
|
31
|
+
All needed configuration files are in ./smailr-etc for review.
|
32
|
+
|
33
|
+
Please install exim4, dovecot and then run the commands below, or
|
34
|
+
adjust the file locations according to your environment.
|
35
|
+
|
36
|
+
Also make sure to configure a location for the SQLite database
|
37
|
+
file in samilr.yml.
|
38
|
+
|
39
|
+
Then run 'smailr migrate' to initialize the database.
|
40
|
+
*****************************************************************
|
41
|
+
|
42
|
+
cp smailr-etc/smailr.yml /etc/smailr.yml
|
43
|
+
cp smailr-etc/dovecot.conf /etc/dovecot/
|
44
|
+
cp smailr-etc/dovecot-sql.conf /etc/dovecot/
|
45
|
+
cp smailr-etc/exim4/
|
46
|
+
|
47
|
+
# invoke-rc.d exim4 restart
|
48
|
+
# invoke-rc.d dovecot restart
|
49
|
+
|
50
|
+
Run the setup command to initialize the smailr database run:
|
51
|
+
|
52
|
+
# smailr migrate
|
53
|
+
|
54
|
+
You should now be ready to just manage your mailserver with the commands listed
|
55
|
+
below.
|
56
|
+
|
57
|
+
## Managing your mailserver
|
58
|
+
|
59
|
+
### Domains
|
60
|
+
|
61
|
+
Add a local domain
|
62
|
+
|
63
|
+
smailr add example.com
|
64
|
+
|
65
|
+
Remove a local domain and all associated mailboxes
|
66
|
+
|
67
|
+
smailr rm example.com
|
68
|
+
|
69
|
+
List all domains
|
70
|
+
|
71
|
+
smailr ls
|
72
|
+
|
73
|
+
### Mailboxes
|
74
|
+
|
75
|
+
Add a new local mailbox. This will interactively ask you for the user password
|
76
|
+
|
77
|
+
smailr add user@example.com
|
78
|
+
|
79
|
+
You can as well specify the password on the CLI
|
80
|
+
|
81
|
+
smailr add user@example.com --password secretpass
|
82
|
+
|
83
|
+
Remove a local mailbox
|
84
|
+
|
85
|
+
smailr rm user@example.com
|
86
|
+
|
87
|
+
List all addresses for a domain
|
88
|
+
|
89
|
+
smailr ls example.com
|
90
|
+
|
91
|
+
Update a users passowrd
|
92
|
+
|
93
|
+
smailr passwd user@example.com
|
94
|
+
|
95
|
+
### Aliases
|
96
|
+
|
97
|
+
Simply add an 'user-alias@example.com' alias to the 'user@example.com' mailbox.
|
98
|
+
|
99
|
+
smailr add user-alias@example.com --alias user@example.com
|
100
|
+
|
101
|
+
To remove the alias again, run the rm command.
|
102
|
+
|
103
|
+
smailr rm user-alias@example.com --alias user@example.com
|
104
|
+
|
105
|
+
You can as well specify multiple destinations for both commands separated by a comma:
|
106
|
+
|
107
|
+
smailr add user-alias@example.com --alias user@example.com,user1@example.com
|
108
|
+
|
109
|
+
### DKIM
|
110
|
+
|
111
|
+
You can even manage RSA keys for Domain Key Identified Mail (DKIM).
|
112
|
+
|
113
|
+
To create a new key for the selector MX do:
|
114
|
+
|
115
|
+
# smailr add example.com --dkim mx
|
116
|
+
public-key MIGJAo<snip>AAE= # returns the public key to use
|
117
|
+
|
118
|
+
To remove the key again run:
|
119
|
+
|
120
|
+
smailr rm example.com --dkim mx
|
121
|
+
|
122
|
+
**IMPORTANT NOTE**: You will need to setup DNS manually for DKIM to work. The
|
123
|
+
above example requires the following DNS records:
|
124
|
+
|
125
|
+
$ORIGIN example.com
|
126
|
+
_domainkey IN TXT "t=y\; o=~\;"
|
127
|
+
mx._domainkey IN TXT "v=DKIM1\; t=y\; k=rsa\; p=MIGJAo<snip>AAE="
|
128
|
+
|
129
|
+
Further explenation:
|
130
|
+
|
131
|
+
'mx' matches up with your dkim_selector specified on you CLI.
|
132
|
+
|
133
|
+
't=y' tells remote MTAs, that you are still testing DKIM.
|
134
|
+
Use t=n once everything works.
|
135
|
+
|
136
|
+
'o=~' tells everybody, that only some may gets signed.
|
137
|
+
Use o=- if you want to sign everything.
|
138
|
+
|
139
|
+
The exim configuration assumes a selector of 'mx' by default. You can change that, so
|
140
|
+
it matches something else. Eg. the current month of the year, in case you want
|
141
|
+
to generate a new key every month.
|
142
|
+
|
143
|
+
Check the remote\_smtp transport configuration in the supplied Exim configuration file
|
144
|
+
to change that.
|
145
|
+
|
146
|
+
### Mutt
|
147
|
+
|
148
|
+
Smailr can launch mutt with the required configuration for a specific mailbox
|
149
|
+
automatically. Open mutt for the specified mailbox:
|
150
|
+
|
151
|
+
smailr mutt user@example.com
|
152
|
+
|
153
|
+
## Compatibility
|
154
|
+
|
155
|
+
Smailr was developed an tested on Debian/Squeeze and should be easily portable
|
156
|
+
to any other system.
|
157
|
+
|
158
|
+
## BUGS
|
159
|
+
|
160
|
+
For bugs or feature requests, please use the GitHub issue tracker.
|
161
|
+
|
162
|
+
https://github.com/sts/smailr/issues
|
163
|
+
|
164
|
+
|
165
|
+
## WHO
|
166
|
+
|
167
|
+
Stefan Schlesinger / sts@ono.at / @stsonoat / http://sts.ono.at
|
168
|
+
|
data/bin/smailr
CHANGED
@@ -3,8 +3,6 @@ $: << File.expand_path('../../lib', __FILE__)
|
|
3
3
|
|
4
4
|
require 'smailr'
|
5
5
|
|
6
|
-
DB = Sequel.connect("sqlite:///etc/exim4/smailr.sqlite")
|
7
|
-
|
8
6
|
#
|
9
7
|
# CLI Helpers
|
10
8
|
#
|
@@ -14,25 +12,27 @@ def determine_object(string)
|
|
14
12
|
end
|
15
13
|
|
16
14
|
def ask_password
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
min_password_length = Smailr.config["password_policy"]["length"]
|
16
|
+
|
17
|
+
password = ask("Password: ") { |q| q.echo = "*" }
|
18
|
+
confirm = ask("Confirm: ") { |q| q.echo = "*" }
|
20
19
|
|
21
20
|
if password != confirm
|
22
21
|
say("Mismatch; try again.")
|
23
22
|
ask_password
|
24
23
|
end
|
25
24
|
|
26
|
-
if password.length < min_password_length
|
25
|
+
if password.length < min_password_length.to_i
|
27
26
|
say("Too short; try again.")
|
28
27
|
ask_password
|
29
28
|
end
|
30
29
|
|
31
|
-
|
30
|
+
password
|
32
31
|
end
|
33
32
|
|
34
33
|
program :version, Smailr::VERSION
|
35
|
-
program :description, 'Simple MAIL
|
34
|
+
program :description, 'Simple MAIL manageR - Virtual mail hosting management from the CLI'
|
35
|
+
|
36
36
|
|
37
37
|
#
|
38
38
|
# Commands
|
@@ -44,9 +44,9 @@ command :add do |c|
|
|
44
44
|
c.example 'Add a mailbox', 'smailr add user@example.com'
|
45
45
|
c.example 'Add an alias', 'smailr add alias@localdom.com --alias user@example.com,user1@example.com'
|
46
46
|
c.example 'Setup DKIM for a domain', 'smailr add ono.at --dkim'
|
47
|
-
c.option '--alias
|
48
|
-
c.option '--password
|
49
|
-
c.option '--dkim',
|
47
|
+
c.option '--alias DESTINATION', String, 'Specify the alias destination.'
|
48
|
+
c.option '--password PASSWORD', String, 'The password for a new mailbox. If you omit this option, it prompts for one.'
|
49
|
+
c.option '--dkim SELECTOR', String, 'Add a DKIM Key with the specified selector for domain.'
|
50
50
|
c.action do |args, options|
|
51
51
|
address = args[0]
|
52
52
|
type = determine_object(address)
|
@@ -54,7 +54,10 @@ command :add do |c|
|
|
54
54
|
case type
|
55
55
|
when :domain
|
56
56
|
if options.dkim
|
57
|
-
|
57
|
+
selector = options.dkim
|
58
|
+
key = Smailr::Dkim.add(address, selector)
|
59
|
+
|
60
|
+
puts "public-key " + key.to_a[1..-2].join.gsub(/\n/, '')
|
58
61
|
else
|
59
62
|
Smailr::Domain.add(address)
|
60
63
|
end
|
@@ -87,7 +90,7 @@ command :ls do |c|
|
|
87
90
|
puts "a: #{aliass.localpart}@#{args[0]} > #{aliass.dstlocalpart}@#{aliass.dstdomain}"
|
88
91
|
end
|
89
92
|
when nil
|
90
|
-
domains = DB[:domains]
|
93
|
+
domains = Smailr::DB[:domains]
|
91
94
|
domains.all.each do |d|
|
92
95
|
domain = Smailr::Model::Domain[:fqdn => d[:fqdn]]
|
93
96
|
puts d[:fqdn]
|
@@ -104,15 +107,16 @@ command :rm do |c|
|
|
104
107
|
c.summary = 'Remove a domain, mailbox or alias known to the mail system.'
|
105
108
|
c.example 'Remove a domain', 'smailr rm example.com'
|
106
109
|
c.option '--force', 'Force the operation, do not ask for confirmation.'
|
107
|
-
c.option '--dkim', 'Remove a dkim key.'
|
108
|
-
c.option '--alias
|
110
|
+
c.option '--dkim SELECTOR', String, 'Remove a dkim key.'
|
111
|
+
c.option '--alias DESTINATION', String, 'Specify the destination you want to remove from the alias.'
|
109
112
|
c.action do |args, options|
|
110
113
|
address = args[0]
|
111
114
|
type = determine_object(address)
|
112
115
|
case type
|
113
116
|
when :domain
|
114
117
|
if options.dkim
|
115
|
-
|
118
|
+
selecotr = options.dkim
|
119
|
+
Smailr::Dkim.rm(address, selector)
|
116
120
|
else
|
117
121
|
Smailr::Domain.rm(address, options.force)
|
118
122
|
end
|
@@ -130,6 +134,25 @@ command :rm do |c|
|
|
130
134
|
end
|
131
135
|
end
|
132
136
|
|
137
|
+
command :passwd do |c|
|
138
|
+
c.syntax = 'smailr passwd mailbox'
|
139
|
+
c.summary = 'Update a users password.'
|
140
|
+
c.action do |args,options|
|
141
|
+
address = args[0]
|
142
|
+
password = ask_password
|
143
|
+
Smailr::Mailbox.update_password(address, password)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
command :setup do |c|
|
149
|
+
c.syntax = 'smailr setup'
|
150
|
+
c.summary = 'Install a required components on a mailserver'
|
151
|
+
c.action do |args,options|
|
152
|
+
Smailr::setup
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
133
156
|
|
134
157
|
command :migrate do |c|
|
135
158
|
c.syntax = 'smailr migrate [options]'
|
@@ -137,12 +160,12 @@ command :migrate do |c|
|
|
137
160
|
c.option '--to VERSION', String, 'Migrate the database to a specifict version.'
|
138
161
|
c.action do |args,options|
|
139
162
|
require 'sequel/extensions/migration'
|
140
|
-
raise "Database not configured" unless DB
|
163
|
+
raise "Database not configured" unless Smailr::DB
|
141
164
|
|
142
165
|
if options.version.nil?
|
143
|
-
Sequel::Migrator.apply(DB, Smailr.migrations_directory)
|
166
|
+
Sequel::Migrator.apply(Smailr::DB, Smailr.migrations_directory)
|
144
167
|
else
|
145
|
-
Sequel::Migrator.apply(DB, Smailr.migrations_directory, :target => options.version.to_i)
|
168
|
+
Sequel::Migrator.apply(Smailr::DB, Smailr.migrations_directory, :target => options.version.to_i)
|
146
169
|
end
|
147
170
|
end
|
148
171
|
end
|
@@ -157,9 +180,9 @@ command :mutt do |c|
|
|
157
180
|
c.example 'Open test@example.com', 'smailr mutt test@example.com'
|
158
181
|
c.action do |args,options|
|
159
182
|
localpart, fqdn = args[0].split('@')
|
160
|
-
`command -v mutt
|
161
|
-
if
|
162
|
-
exec "MAIL=/srv/mail/users/#{fqdn}/#{localpart} MAILDIR=$MAIL mutt -mMaildir
|
183
|
+
mutt = `command -v mutt || { echo "Please install mutt first. Aborting." >&2; exit 1; }`
|
184
|
+
if $?
|
185
|
+
exec "MAIL=/srv/mail/users/#{fqdn}/#{localpart} MAILDIR=$MAIL #{mutt} -mMaildir"
|
163
186
|
end
|
164
187
|
end
|
165
188
|
end
|
data/contrib/exim4.conf
CHANGED
@@ -1,16 +1,29 @@
|
|
1
|
-
|
1
|
+
#############################################################################
|
2
2
|
# Smailr Exim Configuration
|
3
3
|
|
4
|
+
EXIM_CONF = /etc/exim4
|
4
5
|
|
5
|
-
|
6
|
+
SQLITE_DATABASE_FILE = EXIM_CONF/smailr.sqlite
|
6
7
|
|
7
|
-
|
8
|
+
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
|
8
9
|
|
9
|
-
|
10
|
+
DKIM_SELECTOR = mx
|
11
|
+
|
12
|
+
#############################################################################
|
13
|
+
# Database Queries
|
10
14
|
|
11
15
|
VIRTUAL_DOMAINS_SQL = SELECT DISTINCT fqdn FROM domains WHERE fqdn = '${quote_sqlite:$domain}'
|
12
16
|
VIRTUAL_DOMAINS = ${lookup sqlite{SQLITE_DATABASE_FILE VIRTUAL_DOMAINS_SQL}}
|
13
17
|
|
18
|
+
R_VIRTUAL_ALIASES_DATA_SQL = \
|
19
|
+
SELECT aliases.dstlocalpart || '@' || aliases.dstdomain \
|
20
|
+
FROM aliases, domains \
|
21
|
+
WHERE aliases.localpart = '${quote_sqlite:$local_part}' \
|
22
|
+
AND domains.fqdn = '${quote_sqlite:$domain}' \
|
23
|
+
AND aliases.domain_id = domains.id
|
24
|
+
|
25
|
+
R_VIRTUAL_ALIASES_DATA = ${lookup sqlite {SQLITE_DATABASE_FILE R_VIRTUAL_ALIASES_DATA_SQL}{$value}fail}
|
26
|
+
|
14
27
|
R_VIRTUAL_MAILBOX_CONDITION_SQL = \
|
15
28
|
SELECT '/srv/mail/users/' || domains.fqdn || '/' || mailboxes.localpart \
|
16
29
|
FROM mailboxes, domains \
|
@@ -20,7 +33,23 @@ R_VIRTUAL_MAILBOX_CONDITION_SQL = \
|
|
20
33
|
|
21
34
|
R_VIRTUAL_MAILBOX_CONDITION = ${lookup sqlite{SQLITE_DATABASE_FILE R_VIRTUAL_MAILBOX_CONDITION_SQL}}
|
22
35
|
|
23
|
-
|
36
|
+
DKIM_PRIVATE_KEY_SQL = \
|
37
|
+
SELECT private_key \
|
38
|
+
FROM dkims, domains \
|
39
|
+
WHERE dkims.selector = 'mx' \
|
40
|
+
AND domains.fqdn = '${quote_sqlite:DKIM_DOMAIN}' \
|
41
|
+
AND dkims.domain_id = domains.id
|
42
|
+
|
43
|
+
DKIM_PRIVATE_KEY = ${lookup sqlite{SQLITE_DATABASE_FILE DKIM_PRIVATE_KEY_SQL}{$value}fail}
|
44
|
+
|
45
|
+
################################################################################
|
46
|
+
# Domain Lists
|
47
|
+
|
48
|
+
domainlist local_domains = @ : VIRTUAL_DOMAINS
|
49
|
+
|
50
|
+
domainlist relay_to_domains =
|
51
|
+
|
52
|
+
hostlist relay_from_hosts =
|
24
53
|
|
25
54
|
#############################################################################
|
26
55
|
# Main Settings
|
@@ -124,8 +153,6 @@ acl_smtp_expn = deny
|
|
124
153
|
begin acl
|
125
154
|
|
126
155
|
acl_check_rcpt:
|
127
|
-
# TODO: Put up propper spam detection
|
128
|
-
|
129
156
|
# Accept if source is local SMTP (not over TCP). We do this by testing
|
130
157
|
# for an empty sending host field.
|
131
158
|
accept hosts = :
|
@@ -138,15 +165,6 @@ acl_check_rcpt:
|
|
138
165
|
# circumvent relaying restrictions.
|
139
166
|
deny local_parts = ^.*[@%!/|] : ^\\.
|
140
167
|
|
141
|
-
# Don't scan messages with our cryptographic header.
|
142
|
-
# This is needed for messages, which run the ACL twize, (eg. redirects)
|
143
|
-
# to save processing time.
|
144
|
-
warn message = X-SA-Do-Not-Run: Yes
|
145
|
-
condition = ${if eq{\
|
146
|
-
${hmac{md5}{ACL_DONT_SCAN_TWIZE_SECRET}{$body_linecount}}}\
|
147
|
-
{$h_X-Scan-Signature:}\
|
148
|
-
{1}{0}}
|
149
|
-
|
150
168
|
# Accept authenticated messages.
|
151
169
|
accept authenticated = *
|
152
170
|
|
@@ -211,14 +229,8 @@ begin routers
|
|
211
229
|
domains = +local_domains
|
212
230
|
allow_fail
|
213
231
|
allow_defer
|
214
|
-
# Lookup the mailbox which we route to
|
215
|
-
data =
|
216
|
-
SELECT mailboxes.localpart || '@' || domains.fqdn \
|
217
|
-
FROM mailboxes, domains, aliases \
|
218
|
-
WHERE aliases.address = '${quote_sqlite:$local_part}@${quote_sqlite:$domain}' \
|
219
|
-
AND domains.fqdn = '${quote_sqlite:$domain}' \
|
220
|
-
AND mailboxes.domain_id = domains.id \
|
221
|
-
AND aliases.mailbox_id = mailboxes.id }{$value}fail}
|
232
|
+
# Lookup the mailbox which we route the message to
|
233
|
+
data = R_VIRTUAL_ALIASES_DATA
|
222
234
|
|
223
235
|
virtual_mailbox:
|
224
236
|
debug_print = "R: virtual_mailbox for $local_part@$domain"
|
@@ -251,9 +263,11 @@ begin transports
|
|
251
263
|
debug_print = "T: remote_smtp for $local_part@$domain"
|
252
264
|
driver = smtp
|
253
265
|
hosts_nopass_tls = *
|
254
|
-
|
255
|
-
|
256
|
-
|
266
|
+
dkim_domain = DKIM_DOMAIN
|
267
|
+
dkim_selector = DKIM_SELECTOR
|
268
|
+
dkim_private_key = DKIM_PRIVATE_KEY
|
269
|
+
dkim_canon = relaxed
|
270
|
+
dkim_strict = 0
|
257
271
|
|
258
272
|
|
259
273
|
dovecot_virtual_delivery:
|
@@ -268,8 +282,6 @@ begin transports
|
|
268
282
|
log_output
|
269
283
|
user = vmail
|
270
284
|
temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78
|
271
|
-
# Remove the X-SA_Exim-Rcpt-To header again, otherwise we would expose BCCs
|
272
|
-
headers_remove = "X-SA-Exim-Rcpt-To"
|
273
285
|
|
274
286
|
|
275
287
|
#############################################################################
|
@@ -306,3 +318,4 @@ begin authenticators
|
|
306
318
|
AND domains.fqdn = '${quote_sqlite:${domain:$auth2}}' \
|
307
319
|
AND domains.id = mailboxes.domain_id} \
|
308
320
|
{$value}fail}} }} {yes}{no}}"
|
321
|
+
client_condition = ${if !eq{$tls_cipher}{}}
|
data/contrib/install.pp
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
class smailr::mx
|
2
|
+
{
|
3
|
+
include smailr::params
|
4
|
+
include smailr::mx::common
|
5
|
+
include smailr::mx::exim
|
6
|
+
include smailr::mx::dovecot
|
7
|
+
}
|
8
|
+
|
9
|
+
class smailr::params
|
10
|
+
{
|
11
|
+
$smailr_version = "0.5.0"
|
12
|
+
|
13
|
+
$smailr_mailstorage = "/srv/mail"
|
14
|
+
|
15
|
+
$smailr_contrib = $lsbdistcodename ? {
|
16
|
+
"Debian": "/var/lib/ruby/gems/smailr-${version}/contrib",
|
17
|
+
}
|
18
|
+
|
19
|
+
$exim_package_name = $lsbdistid ? {
|
20
|
+
"Debian": "exim4-daemon-heavy"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
class smailr::mx::common
|
25
|
+
{
|
26
|
+
user { "vmail":
|
27
|
+
ensure => present,
|
28
|
+
}
|
29
|
+
|
30
|
+
group { "vmail":
|
31
|
+
ensure => present,
|
32
|
+
}
|
33
|
+
|
34
|
+
file {
|
35
|
+
$smailr_mailstorage:
|
36
|
+
ensure => direcotry,
|
37
|
+
owner => "vmail",
|
38
|
+
group => "vmail",
|
39
|
+
mode => 0660,
|
40
|
+
require => User["vmail"];
|
41
|
+
|
42
|
+
"${smailr_mailstorage}/users":
|
43
|
+
ensure => directory,
|
44
|
+
owner => "vmail",
|
45
|
+
group => "vmail",
|
46
|
+
mode => "0660",
|
47
|
+
require => File["/srv/mail"];
|
48
|
+
}
|
49
|
+
|
50
|
+
}
|
51
|
+
|
52
|
+
class smailr::mx::exim
|
53
|
+
{
|
54
|
+
package { "exim4-daemon-heavy":
|
55
|
+
name => $smailr::params::exim_package_name
|
56
|
+
ensure => present,
|
57
|
+
}
|
58
|
+
|
59
|
+
file {
|
60
|
+
"/etc/exim4/exim4.conf":
|
61
|
+
ensure => present,
|
62
|
+
source => "file:///${smailr_contrib}/exim4.conf"
|
63
|
+
require => Package["exim4-daemon-heavy"];
|
64
|
+
|
65
|
+
"/etc/default/exim4":
|
66
|
+
ensure => present,
|
67
|
+
owner => "root",
|
68
|
+
group => "root",
|
69
|
+
source => "file:///${smailr_contrib}/exim4.defaults",
|
70
|
+
require => Package["exim4-daemon-heavy"];
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
class smailr::mx::dovecot
|
75
|
+
{
|
76
|
+
package { "dovecot-imapd":
|
77
|
+
ensure => present,
|
78
|
+
}
|
79
|
+
|
80
|
+
package { "dovecot-pop3d":
|
81
|
+
ensure => present,
|
82
|
+
}
|
83
|
+
|
84
|
+
file {
|
85
|
+
"/etc/dovecot/dovecot.conf":
|
86
|
+
ensure => present,
|
87
|
+
source => "file:///${smailr_contrib}/dovecot.conf"
|
88
|
+
require => Package["dovecot-imapd"];
|
89
|
+
|
90
|
+
"/etc/dovecot/dovecot.conf":
|
91
|
+
ensure => present,
|
92
|
+
source => "file:///${smailr_contrib}/dovecot-sql.conf"
|
93
|
+
require => Package["dovecot-imapd"];
|
94
|
+
}
|
95
|
+
}
|
data/lib/smailr/dkim.rb
CHANGED
@@ -3,24 +3,26 @@ require 'openssl'
|
|
3
3
|
|
4
4
|
module Smailr
|
5
5
|
module Dkim
|
6
|
-
def self.add(fqdn,
|
7
|
-
options.testing ||= true
|
8
|
-
|
6
|
+
def self.add(fqdn, selector)
|
9
7
|
if not Model::Domain[:fqdn => fqdn]
|
10
8
|
say_error "You trying to add a DKIM key for a non existing domain: #{fqdn}"
|
11
9
|
exit 1
|
12
10
|
end
|
13
11
|
|
14
12
|
private_key, public_key = generate_rsa_key
|
15
|
-
|
16
|
-
dkim.
|
17
|
-
|
18
|
-
|
13
|
+
|
14
|
+
dkim = Model::Dkim.for_domain!(fqdn, selector)
|
15
|
+
dkim.private_key = private_key
|
16
|
+
dkim.public_key = public_key
|
17
|
+
dkim.selector = selector
|
19
18
|
dkim.save
|
19
|
+
|
20
|
+
# Return the key so it can be used for automation
|
21
|
+
dkim.public_key
|
20
22
|
end
|
21
23
|
|
22
|
-
def self.rm(fqdn,
|
23
|
-
dkim = Model::Dkim.for_domain(fqdn)
|
24
|
+
def self.rm(fqdn, selector)
|
25
|
+
dkim = Model::Dkim.for_domain(fqdn, selector)
|
24
26
|
dkim.destroy
|
25
27
|
end
|
26
28
|
|
data/lib/smailr/mailbox.rb
CHANGED
@@ -13,6 +13,12 @@ module Smailr
|
|
13
13
|
mbox.save
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.update_password(address, password)
|
17
|
+
mbox = Model::Mailbox.for_address(address)
|
18
|
+
mbox.password = password
|
19
|
+
mbox.save
|
20
|
+
end
|
21
|
+
|
16
22
|
def self.rm(address, options)
|
17
23
|
mbox = Model::Mailbox.for_address(address)
|
18
24
|
mbox.rm_related
|
data/lib/smailr/model.rb
CHANGED
@@ -17,14 +17,13 @@ module Smailr
|
|
17
17
|
class Dkim < Sequel::Model
|
18
18
|
many_to_one :domain
|
19
19
|
|
20
|
-
def self.for_domain(fqdn)
|
21
|
-
self[:domain => Domain[:fqdn => fqdn]]
|
20
|
+
def self.for_domain(fqdn, selector)
|
21
|
+
self[:domain => Domain[:fqdn => fqdn], :selector => selector]
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.for_domain!(fqdn)
|
25
|
-
find_or_create(:domain => Domain[:fqdn => fqdn])
|
24
|
+
def self.for_domain!(fqdn, selector)
|
25
|
+
find_or_create(:domain => Domain[:fqdn => fqdn], :selector => selector)
|
26
26
|
end
|
27
|
-
one_to_many :aliases
|
28
27
|
end
|
29
28
|
|
30
29
|
class Mailbox < Sequel::Model
|
data/lib/smailr.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'yaml'
|
2
3
|
require 'sqlite3'
|
3
4
|
require 'sequel'
|
4
5
|
require 'commander/import'
|
6
|
+
require 'fileutils'
|
5
7
|
|
6
8
|
module Smailr
|
9
|
+
VERSION = '0.5.0'
|
10
|
+
|
7
11
|
autoload :Model, 'smailr/model'
|
8
12
|
autoload :Domain, 'smailr/domain'
|
9
13
|
autoload :Mailbox, 'smailr/mailbox'
|
@@ -11,12 +15,66 @@ module Smailr
|
|
11
15
|
autoload :Dkim, 'smailr/dkim'
|
12
16
|
|
13
17
|
class << self;
|
18
|
+
attr_accessor :config
|
19
|
+
attr_accessor :load_config
|
14
20
|
attr_accessor :contrib_directory
|
15
21
|
attr_accessor :migrations_directory
|
16
22
|
end
|
17
23
|
|
18
|
-
|
24
|
+
def self.load_config=(files)
|
25
|
+
config = {}
|
26
|
+
files.each do |f|
|
27
|
+
if File.readable?(f)
|
28
|
+
config.merge!(YAML.load_file(f))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
self.config = config
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.db_connect
|
35
|
+
Sequel.connect(self.config['database'])
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def self.setup
|
40
|
+
prefix = self.contrib_directory
|
41
|
+
|
42
|
+
FileUtils.mkdir_p "smailr-etc/exim4"
|
43
|
+
FileUtils.mkdir_p "smailr-etc/dovecot"
|
44
|
+
|
45
|
+
FileUtils.cp File.expand_path("../README.md", prefix), "smailr-etc/"
|
46
|
+
FileUtils.cp File.expand_path("../smailr.yml", prefix), "smailr-etc/"
|
47
|
+
FileUtils.cp File.expand_path("exim4.conf", prefix), "smailr-etc/exim4"
|
48
|
+
FileUtils.cp File.expand_path("dovecot.conf", prefix), "smailr-etc/dovecot"
|
49
|
+
FileUtils.cp File.expand_path("dovecot-sql.conf", prefix),"smailr-etc/dovecot"
|
50
|
+
|
51
|
+
say "*****************************************************************"
|
52
|
+
say "All needed configuration files are in ./smailr-etc for review."
|
53
|
+
say "\n"
|
54
|
+
say "Please install exim4, dovecot and then run the commands below, or"
|
55
|
+
say "adjust the file locations according to your environment."
|
56
|
+
say "\n"
|
57
|
+
say "Also make sure to configure a location for the SQLite database"
|
58
|
+
say "file in smailr.yml."
|
59
|
+
say "\n"
|
60
|
+
say "Then run 'smailr migrate' to initialize the database."
|
61
|
+
say "*****************************************************************"
|
62
|
+
say "\n"
|
63
|
+
say "cp smailr-etc/smailr.yml /etc/smailr.yml"
|
64
|
+
say "cp smailr-etc/dovecot.conf /etc/dovecot/"
|
65
|
+
say "cp smailr-etc/dovecot-sql.conf /etc/dovecot/"
|
66
|
+
say "cp smailr-etc/exim4/"
|
67
|
+
|
68
|
+
# Future version could maybe launch puppet here?
|
69
|
+
#
|
70
|
+
#instalpp = File.expand_path('/install.pp', self.contrib_directory)
|
71
|
+
#if agree("Shall we launch puppet with the manifest from #{installpp}? (yes/no) ")
|
72
|
+
# exec "puppet apply #{installpp}"
|
73
|
+
#end
|
74
|
+
end
|
19
75
|
end
|
20
76
|
|
21
|
-
Smailr.contrib_directory ||=
|
22
|
-
Smailr.migrations_directory ||=
|
77
|
+
Smailr.contrib_directory ||= File.expand_path('../../contrib', __FILE__)
|
78
|
+
Smailr.migrations_directory ||= File.expand_path('../../migrations', __FILE__)
|
79
|
+
Smailr.load_config ||= [ File.expand_path('../../smailr.yml', __FILE__), '/etc/smailr.yml' ]
|
80
|
+
Smailr::DB = Smailr::db_connect
|
data/migrations/004_dkims.rb
CHANGED
@@ -5,8 +5,9 @@ Sequel.migration do
|
|
5
5
|
foreign_key :domain_id
|
6
6
|
String :private_key, :required => true
|
7
7
|
String :public_key, :required => true
|
8
|
-
String :
|
9
|
-
|
8
|
+
String :selector, :required => true
|
9
|
+
|
10
|
+
index [:domain_id, :selector], :unique => true
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
data/smailr.yml
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smailr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Stefan Schlesinger
|
@@ -80,10 +80,13 @@ files:
|
|
80
80
|
- contrib/dovecot-sql.conf
|
81
81
|
- contrib/dovecot.conf
|
82
82
|
- contrib/exim4.conf
|
83
|
+
- contrib/install.pp
|
83
84
|
- migrations/001_domains.rb
|
84
85
|
- migrations/002_mailboxes.rb
|
85
86
|
- migrations/003_aliases.rb
|
86
87
|
- migrations/004_dkims.rb
|
88
|
+
- README.md
|
89
|
+
- smailr.yml
|
87
90
|
homepage: http://github.com/sts/smailr
|
88
91
|
licenses: []
|
89
92
|
|