ConfigLMM 0.2.0 → 0.3.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/Examples/Implemented.mm.yaml +75 -1
  4. data/Plugins/Apps/Authentik/Authentik-Server.container +18 -0
  5. data/Plugins/Apps/Authentik/Authentik-Worker.container +17 -0
  6. data/Plugins/Apps/Authentik/Authentik.conf.erb +35 -0
  7. data/Plugins/Apps/Authentik/Authentik.lmm.rb +73 -0
  8. data/Plugins/Apps/Cassandra/Cassandra.lmm.rb +41 -0
  9. data/Plugins/Apps/Dovecot/Dovecot.lmm.rb +148 -0
  10. data/Plugins/Apps/GitLab/GitLab.conf.erb +26 -0
  11. data/Plugins/Apps/GitLab/GitLab.container +17 -0
  12. data/Plugins/Apps/GitLab/GitLab.lmm.rb +75 -0
  13. data/Plugins/Apps/Nextcloud/Nextcloud.conf.erb +48 -10
  14. data/Plugins/Apps/Nextcloud/Nextcloud.lmm.rb +59 -2
  15. data/Plugins/Apps/Nextcloud/config.php +18 -0
  16. data/Plugins/Apps/Nginx/conf.d/configlmm.conf +62 -0
  17. data/Plugins/Apps/Nginx/config-lmm/errors.conf +1 -1
  18. data/Plugins/Apps/Nginx/main.conf.erb +31 -0
  19. data/Plugins/Apps/Nginx/nginx.conf +3 -68
  20. data/Plugins/Apps/Nginx/nginx.lmm.rb +71 -14
  21. data/Plugins/Apps/Odoo/Odoo.conf.erb +30 -13
  22. data/Plugins/Apps/Odoo/Odoo.container +17 -0
  23. data/Plugins/Apps/Odoo/Odoo.lmm.rb +62 -2
  24. data/Plugins/Apps/Odoo/odoo.conf +37 -0
  25. data/Plugins/Apps/PHP-FPM/PHP-FPM.lmm.rb +95 -0
  26. data/Plugins/Apps/Peppermint/Peppermint.conf.erb +64 -0
  27. data/Plugins/Apps/Peppermint/Peppermint.container +14 -0
  28. data/Plugins/Apps/Peppermint/Peppermint.lmm.rb +58 -0
  29. data/Plugins/Apps/Postfix/Postfix.lmm.rb +139 -31
  30. data/Plugins/Apps/Postfix/smtpd.conf +3 -0
  31. data/Plugins/Apps/PostgreSQL/PostgreSQL.lmm.rb +172 -23
  32. data/Plugins/Apps/SSH/SSH.lmm.rb +51 -0
  33. data/Plugins/Apps/UVdesk/UVdesk.conf.erb +52 -0
  34. data/Plugins/Apps/UVdesk/UVdesk.lmm.rb +85 -0
  35. data/Plugins/Apps/Valkey/Valkey.lmm.rb +2 -1
  36. data/Plugins/Apps/Vaultwarden/Vaultwarden.conf.erb +35 -18
  37. data/Plugins/Apps/Vaultwarden/Vaultwarden.container +16 -0
  38. data/Plugins/Apps/Vaultwarden/Vaultwarden.lmm.rb +42 -3
  39. data/Plugins/Apps/gollum/gollum.conf.erb +45 -18
  40. data/Plugins/Apps/gollum/gollum.container +12 -0
  41. data/Plugins/Apps/gollum/gollum.lmm.rb +39 -10
  42. data/Plugins/OS/Linux/Distributions.yaml +10 -0
  43. data/Plugins/OS/Linux/Linux.lmm.rb +145 -12
  44. data/Plugins/OS/Linux/Packages.yaml +42 -4
  45. data/Plugins/OS/Linux/WireGuard/WireGuard.lmm.rb +108 -0
  46. data/Plugins/OS/Linux/WireGuard/wg0.conf.erb +15 -0
  47. data/Plugins/OS/Linux/systemd/systemd.lmm.rb +28 -0
  48. data/Plugins/OS/Linux/systemd/user-0.slice +9 -0
  49. data/Plugins/OS/Linux/systemd/user@.service.d/delegate.conf +3 -0
  50. data/Plugins/Platforms/GoDaddy/GoDaddy.lmm.rb +6 -2
  51. data/Plugins/Services/DNS/PowerDNS.lmm.rb +69 -6
  52. data/README.md +6 -0
  53. data/bootstrap.sh +54 -0
  54. data/lib/ConfigLMM/Framework/plugins/dns.rb +1 -2
  55. data/lib/ConfigLMM/Framework/plugins/linuxApp.rb +157 -35
  56. data/lib/ConfigLMM/Framework/plugins/nginxApp.rb +24 -6
  57. data/lib/ConfigLMM/Framework/plugins/plugin.rb +52 -12
  58. data/lib/ConfigLMM/version.rb +1 -1
  59. metadata +31 -3
  60. data/Plugins/Apps/Nginx/main.conf +0 -30
@@ -3,6 +3,9 @@ module ConfigLMM
3
3
  module LMM
4
4
  class Odoo < Framework::NginxApp
5
5
 
6
+ USER = 'odoo'
7
+ HOME_DIR = '/var/lib/odoo'
8
+
6
9
  def actionOdooBuild(id, target, state, context, options)
7
10
  writeNginxConfig(__dir__, 'Odoo', id, target, state, context, options)
8
11
  end
@@ -12,12 +15,69 @@ module ConfigLMM
12
15
  end
13
16
 
14
17
  def actionOdooDeploy(id, target, activeState, context, options)
15
- if !target['Location'] || target['Location'] == '@me'
16
- deployNginxConfig(id, target, activeState, context, options)
18
+ target['Database'] ||= {}
19
+ if target['Location'] && target['Location'] != '@me'
20
+ uri = Addressable::URI.parse(target['Location'])
21
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
22
+
23
+ self.class.sshStart(uri) do |ssh|
24
+
25
+ if !target.key?('Proxy') || target['Proxy'] != 'only'
26
+ dbPassword = self.configurePostgreSQL(target['Database'], ssh)
27
+ distroInfo = Framework::LinuxApp.currentDistroInfo(ssh)
28
+ Framework::LinuxApp.configurePodmanServiceOverSSH(USER, HOME_DIR, 'Odoo', distroInfo, ssh)
29
+ self.class.sshExec!(ssh, "su --login #{USER} --shell /bin/sh --command 'mkdir -p ~/config'")
30
+ self.class.sshExec!(ssh, "su --login #{USER} --shell /bin/sh --command 'mkdir -p ~/data'")
31
+ self.class.sshExec!(ssh, "su --login #{USER} --shell /bin/sh --command 'mkdir -p ~/addons'")
32
+
33
+ path = Framework::LinuxApp::SYSTEMD_CONTAINERS_PATH.gsub('~', HOME_DIR)
34
+ dbHost = '10.0.2.2'
35
+ dbHost = target['Database']['HostName'] if target['Database']['HostName']
36
+
37
+ self.class.sshExec!(ssh, " echo 'HOST=#{dbHost}' > #{path}/Odoo.env")
38
+ self.class.sshExec!(ssh, " echo 'USER=#{USER}' >> #{path}/Odoo.env")
39
+ self.class.sshExec!(ssh, " echo 'PASSWORD=#{dbPassword}' >> #{path}/Odoo.env")
40
+ self.class.sshExec!(ssh, "chown #{USER}:#{USER} #{path}/Odoo.env")
41
+ self.class.sshExec!(ssh, "chmod 600 #{path}/Odoo.env")
42
+
43
+ ssh.scp.upload!(__dir__ + '/Odoo.container', path)
44
+ ssh.scp.upload!(__dir__ + '/odoo.conf', HOME_DIR + '/config/')
45
+ self.class.sshExec!(ssh, "chown #{USER}:#{USER} #{HOME_DIR}/config/odoo.conf")
46
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ daemon-reload")
47
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ start Odoo")
48
+ end
49
+
50
+ if !target.key?('Proxy') || target['Proxy'] == true || target['Proxy'] == 'only'
51
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
52
+
53
+ Framework::LinuxApp.ensurePackages([NGINX_PACKAGE], ssh)
54
+ Framework::LinuxApp.ensureServiceAutoStartOverSSH(NGINX_PACKAGE, ssh)
55
+ self.class.prepareNginxConfig(target, ssh)
56
+ self.writeNginxConfig(__dir__, 'Odoo', id, target, state, context, options)
57
+ self.deployNginxConfig(id, target, activeState, context, options)
58
+ Framework::LinuxApp.startServiceOverSSH(NGINX_PACKAGE, ssh)
59
+ end
60
+
61
+ Framework::LinuxApp.firewallAddPortOverSSH('8069/tcp', uri)
62
+ end
63
+ else
64
+ if !target.key?('Proxy') || target['Proxy'] == true || target['Proxy'] == 'only'
65
+ deployNginxConfig(id, target, activeState, context, options)
66
+ end
17
67
  activeState['Location'] = '@me'
18
68
  end
19
69
  end
20
70
 
71
+ def configurePostgreSQL(settings, ssh)
72
+ user = USER
73
+ password = SecureRandom.alphanumeric(20)
74
+ PostgreSQL.executeRemotelyOverSSH(settings, ssh) do |ssh|
75
+ self.class.sshExec!(ssh, "su --login #{PostgreSQL::USER_NAME} --command 'createuser --createdb #{user}'", true)
76
+ PostgreSQL.executeSQL("ALTER USER #{user} WITH PASSWORD '#{password}'", nil, ssh)
77
+ end
78
+ password
79
+ end
80
+
21
81
  end
22
82
  end
23
83
  end
@@ -0,0 +1,37 @@
1
+ [options]
2
+ addons_path = /mnt/extra-addons
3
+ data_dir = /var/lib/odoo
4
+ ; admin_passwd = admin
5
+ ; csv_internal_sep = ,
6
+ ; db_maxconn = 64
7
+ ; db_name = False
8
+ ; db_template = template1
9
+ ; dbfilter = .*
10
+ ; debug_mode = False
11
+ ; email_from = False
12
+ ; limit_memory_hard = 2684354560
13
+ ; limit_memory_soft = 2147483648
14
+ ; limit_request = 8192
15
+ ; limit_time_cpu = 60
16
+ ; limit_time_real = 120
17
+ list_db = False
18
+ ; log_db = False
19
+ ; log_handler = [':INFO']
20
+ ; log_level = info
21
+ ; logfile = None
22
+ ; longpolling_port = 8072
23
+ ; max_cron_threads = 2
24
+ ; osv_memory_age_limit = 1.0
25
+ ; osv_memory_count_limit = False
26
+ ; smtp_password = False
27
+ ; smtp_port = 25
28
+ ; smtp_server = localhost
29
+ ; smtp_ssl = False
30
+ ; smtp_user = False
31
+ ; workers = 0
32
+ ; xmlrpc = True
33
+ ; xmlrpc_interface =
34
+ ; xmlrpc_port = 8069
35
+ ; xmlrpcs = True
36
+ ; xmlrpcs_interface =
37
+ ; xmlrpcs_port = 8071
@@ -0,0 +1,95 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class PHP_FPM < Framework::LinuxApp
5
+
6
+ PHPFPM_PACKAGE = 'PHP-FPM'
7
+ PHPFPM_SERVICE = 'php-fpm'
8
+
9
+ def self.writeConfig(name, target, distroInfo, configLines)
10
+ target['PHP-FPM'] ||= {}
11
+
12
+ configLines << "[#{name}]\n"
13
+ configLines << "user = #{target['User']}\n"
14
+ configLines << "group = #{target['User']}\n"
15
+ if target['Listen']
16
+ configLines << "listen = #{target['Listen']}\n"
17
+ else
18
+ configLines << "listen = /run/php-fpm/#{name}.sock\n"
19
+ configLines << "listen.owner = #{target['User']}\n"
20
+ group = 'http'
21
+ group = 'nginx' if distroInfo['Name'] == 'openSUSE Leap'
22
+ configLines << "listen.group = #{group}\n"
23
+ end
24
+ configLines << "pm = dynamic\n"
25
+ configLines << "pm.max_children = 5\n"
26
+ configLines << "pm.min_spare_servers = 1\n"
27
+ configLines << "pm.max_spare_servers = 3\n"
28
+ configLines << "pm.start_servers = 2\n"
29
+ configLines << "access.log = /var/log/php/$pool.access.log\n"
30
+ if target['PHP-FPM']['chdir']
31
+ configLines << "chdir = #{target['PHP-FPM']['chdir']}\n"
32
+ else
33
+ configLines << "chdir = #{self.webappsDir(distroInfo)}$pool\n"
34
+ end
35
+ configLines << "php_admin_value[error_log] = /var/log/php/$pool.errors.log\n"
36
+ configLines << "php_admin_flag[log_errors] = on\n"
37
+ configLines << "php_admin_value[memory_limit] = 1G\n"
38
+ configLines << "php_admin_value[mail.log] = /var/log/php/$pool.mail.log\n"
39
+ end
40
+
41
+ def self.phpConfig(distroInfo)
42
+ if distroInfo['Name'] == 'openSUSE Leap'
43
+ '/etc/php8/fpm/php.ini'
44
+ else
45
+ '/etc/php/php.ini'
46
+ end
47
+ end
48
+
49
+ def self.peclInstallOverSSH(name, ssh)
50
+ self.sshExec!(ssh, "printf \"\\n\" | pecl install #{name}", true)
51
+ end
52
+
53
+ def self.enableExtensionOverSSH(name, distroInfo, ssh)
54
+ phpFile = self.phpConfig(distroInfo)
55
+ if self.remoteFileContains?(phpFile, "extension=#{name}", ssh)
56
+ self.sshExec!(ssh, "sed -i 's|^;extension=#{name}|extension=#{name}|' #{phpFile}")
57
+ else
58
+ self.sshExec!(ssh, "sed -i 's|extension=zip|extension=zip\\nextension=#{name}|' #{phpFile}")
59
+ end
60
+ end
61
+
62
+ def self.configFileDir(distroInfo)
63
+ if distroInfo['Name'] == 'openSUSE Leap'
64
+ '/etc/php8/fpm/'
65
+ else
66
+ '/etc/php/'
67
+ end
68
+ end
69
+
70
+ def self.configDir(distroInfo)
71
+ if distroInfo['Name'] == 'openSUSE Leap'
72
+ '/etc/php8/fpm/php-fpm.d/'
73
+ else
74
+ '/etc/php/php-fpm.d/'
75
+ end
76
+ end
77
+
78
+ def self.webappsDir(distroInfo)
79
+ if distroInfo['Name'] == 'openSUSE Leap'
80
+ '/srv/www/htdocs/'
81
+ else
82
+ '/usr/share/webapps/'
83
+ end
84
+ end
85
+
86
+ def self.fixConfigFileOverSSH(distroInfo, ssh)
87
+ dir = self.configFileDir(distroInfo)
88
+ if !self.remoteFilePresent?(dir + 'php-fpm.conf', ssh)
89
+ self.sshExec!(ssh, "cp #{dir}php-fpm.conf.default #{dir}php-fpm.conf")
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,64 @@
1
+
2
+ server {
3
+ listen 80;
4
+ listen [::]:80;
5
+ server_name peppermint.example.com;
6
+ add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
7
+
8
+ <% if !config['TLS'] %>
9
+ listen <%= config['Port'] %>;
10
+ listen [::]:<%= config['Port'] %>;
11
+ <% else %>
12
+ <% if config['NginxVersion'] >= 1.25 %>
13
+ listen <%= config['Port'] %> ssl;
14
+ listen [::]:<%= config['Port'] %> ssl;
15
+ http2 on;
16
+ http3 on;
17
+ quic_retry on;
18
+ add_header Alt-Svc 'h3=":<%= config['Port'] %>"; ma=86400';
19
+ <% else %>
20
+ listen <%= config['Port'] %> ssl http2;
21
+ listen [::]:<%= config['Port'] %> ssl http2;
22
+ <% end %>
23
+
24
+ include config-lmm/ssl.conf;
25
+ <% end %>
26
+
27
+ server_name <%= config['Domain'] %>;
28
+
29
+ access_log /var/log/nginx/peppermint.access.log;
30
+ error_log /var/log/nginx/peppermint.error.log;
31
+
32
+ include config-lmm/errors.conf;
33
+ include config-lmm/security.conf;
34
+
35
+ client_max_body_size 10M;
36
+
37
+ location / {
38
+ <% if config['Server'] %>
39
+ proxy_pass <%= config['Server'] %>;
40
+ <% else %>
41
+ proxy_pass http://127.0.0.1:13000;
42
+ <% end %>
43
+
44
+ proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
45
+
46
+ include config-lmm/proxy.conf;
47
+ proxy_redirect off;
48
+ proxy_read_timeout 5m;
49
+ }
50
+
51
+ location /api/ {
52
+ <% if config['Server'] %>
53
+ proxy_pass <%= config['Server'] %>;
54
+ <% else %>
55
+ proxy_pass http://127.0.0.1:15003/;
56
+ <% end %>
57
+
58
+ proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
59
+
60
+ include config-lmm/proxy.conf;
61
+ proxy_redirect off;
62
+ proxy_read_timeout 5m;
63
+ }
64
+ }
@@ -0,0 +1,14 @@
1
+
2
+ [Unit]
3
+ Description=Peppermint Ticket Management container
4
+ After=local-fs.target
5
+
6
+ [Container]
7
+ Image=pepperlabs/peppermint:latest
8
+ EnvironmentFile=/var/lib/peppermint/.config/containers/systemd/Peppermint.env
9
+ Network=slirp4netns:allow_host_loopback=true
10
+ PublishPort=127.0.0.1:13000:3000
11
+ PublishPort=127.0.0.1:15003:5003
12
+
13
+ [Install]
14
+ WantedBy=multi-user.target default.target
@@ -0,0 +1,58 @@
1
+
2
+ module ConfigLMM
3
+ module LMM
4
+ class Peppermint < Framework::NginxApp
5
+
6
+ USER = 'peppermint'
7
+ HOME_DIR = '/var/lib/peppermint'
8
+ HOST_IP = '10.0.2.2'
9
+
10
+ def actionPeppermintDeploy(id, target, activeState, context, options)
11
+ raise Framework::PluginProcessError.new('Domain field must be set!') unless target['Domain']
12
+
13
+ target['Database'] ||= {}
14
+ if target['Location'] && target['Location'] != '@me'
15
+ uri = Addressable::URI.parse(target['Location'])
16
+ raise Framework::PluginProcessError.new("#{id}: Unknown Protocol: #{uri.scheme}!") if uri.scheme != 'ssh'
17
+
18
+ self.class.sshStart(uri) do |ssh|
19
+
20
+ dbPassword = self.configurePostgreSQL(target['Database'], ssh)
21
+ distroInfo = Framework::LinuxApp.currentDistroInfo(ssh)
22
+ Framework::LinuxApp.configurePodmanServiceOverSSH(USER, HOME_DIR, 'Peppermint Ticket Management', distroInfo, ssh)
23
+
24
+ path = Framework::LinuxApp::SYSTEMD_CONTAINERS_PATH.gsub('~', HOME_DIR)
25
+ self.class.sshExec!(ssh, " echo 'DB_HOST=#{HOST_IP}' > #{path}/Peppermint.env")
26
+ self.class.sshExec!(ssh, " echo 'DB_USERNAME=#{USER}' >> #{path}/Peppermint.env")
27
+ self.class.sshExec!(ssh, " echo 'DB_PASSWORD=#{dbPassword}' >> #{path}/Peppermint.env")
28
+ self.class.sshExec!(ssh, " echo 'SECRET=#{SecureRandom.urlsafe_base64(60)}' >> #{path}/Peppermint.env")
29
+ self.class.sshExec!(ssh, " echo 'API_URL=https://#{target['Domain']}/api' >> #{path}/Peppermint.env")
30
+ self.class.sshExec!(ssh, "chown #{USER}:#{USER} #{path}/Peppermint.env")
31
+ self.class.sshExec!(ssh, "chmod 600 #{path}/Peppermint.env")
32
+
33
+ ssh.scp.upload!(__dir__ + '/Peppermint.container', path)
34
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ daemon-reload")
35
+ self.class.sshExec!(ssh, "systemctl --user --machine=#{USER}@ start Peppermint")
36
+
37
+ Framework::LinuxApp.ensurePackages([NGINX_PACKAGE], ssh)
38
+ Framework::LinuxApp.ensureServiceAutoStartOverSSH(NGINX_PACKAGE, ssh)
39
+ self.class.prepareNginxConfig(target, ssh)
40
+ self.writeNginxConfig(__dir__, 'Peppermint', id, target, state, context, options)
41
+ self.deployNginxConfig(id, target, activeState, context, options)
42
+ Framework::LinuxApp.startServiceOverSSH(NGINX_PACKAGE, ssh)
43
+ end
44
+ else
45
+ # TODO
46
+ end
47
+ end
48
+
49
+ def configurePostgreSQL(settings, ssh)
50
+ password = SecureRandom.alphanumeric(20)
51
+ PostgreSQL.createRemoteUserAndDBOverSSH(settings, USER, password, ssh)
52
+ password
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+
@@ -4,12 +4,12 @@ module ConfigLMM
4
4
  class Postfix < Framework::Plugin
5
5
  PACKAGE_NAME = 'Postfix'
6
6
  SERVICE_NAME = 'postfix'
7
- MASTER_FILE = '/etc/postfix/master.cf'
8
- MAIN_FILE = '/etc/postfix/main.cf'
9
- TRANSPORT_FILE = '/etc/postfix/transport'
7
+ MASTER_FILE = 'master.cf'
8
+ MAIN_FILE = 'main.cf'
9
+ TRANSPORT_FILE = 'transport'
10
10
 
11
11
  def actionPostfixDeploy(id, target, activeState, context, options)
12
- plugins[:Linux].ensurePackage(PACKAGE_NAME, target['Location'])
12
+ plugins[:Linux].ensurePackages([PACKAGE_NAME, 'CyrusSASL'], target['Location'])
13
13
  plugins[:Linux].ensureServiceAutoStart(SERVICE_NAME, target['Location'])
14
14
 
15
15
  deploySettings(target, target['Location'], options)
@@ -18,54 +18,162 @@ module ConfigLMM
18
18
  end
19
19
 
20
20
  def deploySettings(target, location, options)
21
+ postfixDirName = 'postfix'
22
+ postfixDirName = 'postfix-' + target['Instance'] if target['Instance']
23
+ postfixDir = '/etc/' + postfixDirName + '/'
21
24
  if location && location != '@me'
22
- if target['AlternativePort']
23
- updateRemoteFile(location, MASTER_FILE, options, true) do |fileLines|
24
- fileLines << "#{target['AlternativePort']} inet n - n - - smtpd\n"
25
- end
26
- end
27
25
  self.class.sshStart(location) do |ssh|
28
- domain = self.class.sshExec!(ssh, "hostname --fqdn").strip
29
- command = "sed -i 's|^myhostname = .*|myhostname = #{domain}|' #{MAIN_FILE}"
30
- command = "sed -i 's|^#myhostname = virtual.domain.tld|myhostname = #{domain}|' #{MAIN_FILE}"
26
+ if target['Instance']
27
+ self.class.sshExec!(ssh, "postmulti -e init")
28
+ self.class.sshExec!(ssh, "postmulti -I #{postfixDirName} -e create", true)
29
+ self.class.sshExec!(ssh, "sed -i 's|^master_service_disable|#master_service_disable|' #{postfixDir + MAIN_FILE}")
30
+ end
31
+ self.class.sshExec!(ssh, "sed -i 's|^tlsmgr|#tlsmgr|' #{postfixDir + MASTER_FILE}")
32
+ if target.key?('SMTP')
33
+ if !target['SMTP'] || target['SMTP'] == 'unix'
34
+ self.class.sshExec!(ssh, "sed -i 's|^smtp|#smtp|' #{postfixDir + MASTER_FILE}")
35
+ end
36
+ end
37
+ updateRemoteFile(ssh, postfixDir + MASTER_FILE, options, true) do |fileLines|
38
+ if target['AlternativePort']
39
+ fileLines << "#{target['AlternativePort']} inet n - n - - smtpd\n"
40
+ fileLines << "tlsmgr unix - - n 1000? 1 tlsmgr\n"
41
+ else
42
+ if !target.key?('Submission') || (target.key?('Submission') && target['Submission'])
43
+ fileLines << "submissions inet n - n - - smtpd\n"
44
+ fileLines << " -o syslog_name=postfix/submissions\n"
45
+ fileLines << " -o smtpd_tls_wrappermode=yes\n"
46
+ fileLines << " -o smtpd_tls_security_level=encrypt\n"
47
+ fileLines << " -o smtpd_sasl_auth_enable=yes\n"
48
+ fileLines << " -o cleanup_service_name=header_cleanup\n"
49
+ fileLines << "header_cleanup unix n - - - 0 cleanup\n"
50
+ fileLines << " -o header_checks=regexp:/etc/postfix/header_cleanup\n"
51
+
52
+ self.class.sshExec!(ssh, "echo '/^Received:/ IGNORE' > /etc/postfix/header_cleanup")
53
+ self.class.sshExec!(ssh, "echo '/^User-Agent:/ IGNORE' >> /etc/postfix/header_cleanup")
54
+ end
55
+ fileLines << "tlsmgr unix - - n 1000? 1 tlsmgr\n"
56
+ if target['SMTP'] == 'unix'
57
+ fileLines << "smtp unix - - n - - smtp\n"
58
+ end
59
+ end
60
+ fileLines
61
+ end
62
+
63
+ domain = target['Domain']
64
+ domain = self.class.sshExec!(ssh, "hostname --fqdn").strip unless domain
65
+ command = "sed -i 's|^myhostname = .*|myhostname = #{domain}|' #{postfixDir + MAIN_FILE}"
31
66
  self.class.sshExec!(ssh, command)
32
- end
33
- if target['Settings']
67
+ command = "sed -i 's|^#myhostname = virtual.domain.tld|myhostname = #{domain}|' #{postfixDir + MAIN_FILE}"
68
+ self.class.sshExec!(ssh, command)
69
+
70
+ # Fix config bug
71
+ command = "sed -i 's|^alias_maps = :/etc/aliases|alias_maps = lmdb:/etc/aliases|' #{postfixDir + MAIN_FILE}"
72
+ self.class.sshExec!(ssh, command)
73
+ command = "sed -i 's|^canonical_maps = :/etc/postfix/canonical|canonical_maps = lmdb:/etc/postfix/canonical|' #{postfixDir + MAIN_FILE}"
74
+ self.class.sshExec!(ssh, command)
75
+ command = "sed -i 's|^relocated_maps = :/etc/postfix/relocated|relocated_maps = lmdb:/etc/postfix/relocated|' #{postfixDir + MAIN_FILE}"
76
+ self.class.sshExec!(ssh, command)
77
+ command = "sed -i 's|^sender_canonical_maps = :/etc/postfix/sender_canonical|sender_canonical_maps = lmdb:/etc/postfix/sender_canonical|' #{postfixDir + MAIN_FILE}"
78
+ self.class.sshExec!(ssh, command)
79
+ command = "sed -i 's|^transport_maps = :/etc/postfix/transport|transport_maps = lmdb:/etc/postfix/transport|' #{postfixDir + MAIN_FILE}"
80
+ self.class.sshExec!(ssh, command)
81
+ command = "sed -i 's|^smtpd_sender_restrictions = :/etc/postfix/access|smtpd_sender_restrictions = lmdb:/etc/postfix/access|' #{postfixDir + MAIN_FILE}"
82
+ self.class.sshExec!(ssh, command)
83
+ command = "sed -i 's|^virtual_alias_maps = :/etc/postfix/virtual|virtual_alias_maps = lmdb:/etc/postfix/virtual|' #{postfixDir + MAIN_FILE}"
84
+ self.class.sshExec!(ssh, command)
85
+ command = "sed -i 's|^relay_domains = $mydestination :/etc/postfix/relay|relay_domains = $mydestination lmdb:/etc/postfix/relay|' #{postfixDir + MAIN_FILE}"
86
+ self.class.sshExec!(ssh, command)
87
+ command = "sed -i 's|^relay_recipient_maps = :/etc/postfix/relay_recipients|relay_recipient_maps = lmdb:/etc/postfix/relay_recipients|' #{postfixDir + MAIN_FILE}"
88
+ self.class.sshExec!(ssh, command)
89
+ command = "sed -i 's|^virtual_mailbox_maps =.*|virtual_mailbox_maps = lmdb:/etc/postfix/mailboxes|' #{postfixDir + MAIN_FILE}"
90
+ self.class.sshExec!(ssh, command)
91
+
92
+
93
+ if target['AlternativePort']
94
+ self.class.sshExec!(ssh, "firewall-cmd -q --add-port='#{target['AlternativePort']}/tcp'")
95
+ self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-port='#{target['AlternativePort']}/tcp'")
96
+ else
97
+ self.class.sshExec!(ssh, "firewall-cmd -q --add-service='smtp'")
98
+ self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-service='smtp'")
99
+ end
100
+ self.class.sshExec!(ssh, "firewall-cmd -q --add-service='smtps'")
101
+ self.class.sshExec!(ssh, "firewall-cmd -q --permanent --add-service='smtps'")
102
+
103
+ ssh.scp.upload!(__dir__ + '/smtpd.conf', '/etc/sasl2/smtpd.conf')
104
+ self.class.sshExec!(ssh, "touch /etc/sasldb2")
105
+ self.class.sshExec!(ssh, "chown postfix:postfix /etc/sasldb2")
106
+ self.class.sshExec!(ssh, "touch #{postfixDir}access")
107
+ self.class.sshExec!(ssh, "postmap #{postfixDir}access")
108
+ self.class.sshExec!(ssh, "touch #{postfixDir}sender_login")
109
+ self.class.sshExec!(ssh, "postmap #{postfixDir}sender_login")
110
+
111
+ certDir = Framework::LinuxApp.createCertificateOverSSH(ssh)
112
+ target['Settings'] ||= []
113
+ target['Settings']['smtpd_sender_login_maps'] = "lmdb:#{postfixDir}sender_login" unless target['Settings']['smtpd_sender_login_maps']
114
+ target['Settings']['smtpd_sender_restrictions'] = "reject_sender_login_mismatch, lmdb:#{postfixDir}access" unless target['Settings']['smtpd_sender_restrictions']
115
+ target['Settings']['smtp_tls_security_level'] = 'may' unless target['Settings']['smtp_tls_security_level']
116
+ target['Settings']['smtpd_tls_mandatory_protocols'] = '>=TLSv1.2' unless target['Settings']['smtpd_tls_mandatory_protocols']
117
+ target['Settings']['smtpd_tls_auth_only'] = 'yes' unless target['Settings']['smtpd_tls_auth_only']
118
+ target['Settings']['smtpd_tls_security_level'] = 'may' unless target['Settings']['smtpd_tls_security_level']
119
+ target['Settings']['smtpd_tls_cert_file'] = certDir + 'fullchain.pem' unless target['Settings']['smtpd_tls_cert_file']
120
+ target['Settings']['smtpd_tls_key_file'] = certDir + 'privkey.pem' unless target['Settings']['smtpd_tls_key_file']
121
+ target['Settings']['tls_preempt_cipherlist'] = 'yes' unless target['Settings']['tls_preempt_cipherlist']
122
+ target['Settings']['tls_ssl_options'] = 'NO_RENEGOTIATION' unless target['Settings']['tls_ssl_options']
123
+
124
+
34
125
  target['Settings'].each do |name, value|
35
- self.class.sshStart(location) do |ssh|
36
- command = "sed -i 's|^#{name} =.*|#{name} = #{value}|' #{MAIN_FILE}"
37
- self.class.sshExec!(ssh, command)
126
+ command = "sed -i 's|^#{name} =.*|##{name} = #{value}|' #{postfixDir + MAIN_FILE}"
127
+ self.class.sshExec!(ssh, command)
128
+ end
129
+ updateRemoteFile(ssh, postfixDir + MAIN_FILE, options) do |fileLines|
130
+ target['Settings'].each do |name, value|
131
+ value = 'yes' if value == true
132
+ value = 'no' if value == false
133
+ fileLines << "#{name} = #{value}\n"
38
134
  end
135
+ fileLines
39
136
  end
40
- end
41
- if target['ForwardAll']
42
- updateRemoteFile(location, TRANSPORT_FILE, options, true) do |fileLines|
43
- hostname, port = target['ForwardAll'].split(':')
44
- hostname = '[' + hostname + ']'
45
- line = '* smtp:' + hostname
46
- line += ':' + port if port
47
- fileLines << line + "\n"
137
+
138
+ if target['ForwardDovecot']
139
+ command = "sed -i 's|^#virtual_transport =.*|virtual_transport = lmtp:unix:/run/dovecot/lmtp|' #{postfixDir + MAIN_FILE}"
140
+ self.class.sshExec!(ssh, command)
48
141
  end
49
- self.class.sshStart(location) do |ssh|
50
- self.class.sshExec!(ssh, "postmap #{TRANSPORT_FILE}")
142
+
143
+ if target['ForwardAll']
144
+ command = "sed -i 's|^transport_maps =.*|transport_maps = lmdb:#{postfixDir}transport|' #{postfixDir + MAIN_FILE}"
145
+ self.class.sshExec!(ssh, command)
146
+ updateRemoteFile(ssh, postfixDir + TRANSPORT_FILE, options, true) do |fileLines|
147
+ hostname, port = target['ForwardAll'].split(':')
148
+ hostname = '[' + hostname + ']'
149
+ line = '* smtp:' + hostname
150
+ line += ':' + port if port
151
+ fileLines << line + "\n"
152
+ end
153
+ self.class.sshExec!(ssh, "postmap #{postfixDir + TRANSPORT_FILE}")
154
+ end
155
+
156
+ if target['Instance']
157
+ self.class.sshExec!(ssh, "postmulti -i #{postfixDirName} -e enable")
158
+ self.class.sshExec!(ssh, "postmulti -i #{postfixDirName} -p start", true)
51
159
  end
52
160
  end
53
161
  else
54
162
  if target['AlternativePort']
55
- updateLocalFile(MASTER_FILE, options, true) do |fileLines|
163
+ updateLocalFile(postfixDir + MASTER_FILE, options, true) do |fileLines|
56
164
  fileLines << "#{target['AlternativePort']} inet n - n - - smtpd\n"
57
165
  end
58
166
  end
59
167
  if target['Settings']
60
168
  target['Settings'].each do |name, value|
61
- `sed -i 's|^#{name} =.*|#{name} = #{value}|' #{MAIN_FILE}`
169
+ `sed -i 's|^#{name} =.*|#{name} = #{value}|' #{postfixDir + MAIN_FILE}`
62
170
  end
63
171
  end
64
172
  if target['ForwardAll']
65
- updateLocalFile(TRANSPORT_FILE, options, true) do |fileLines|
173
+ updateLocalFile(postfixDir + TRANSPORT_FILE, options, true) do |fileLines|
66
174
  fileLines << '* smtp:[' + target['ForwardAll'] + "]\n"
67
175
  end
68
- `postmap #{TRANSPORT_FILE}`
176
+ `postmap #{postfixDir + TRANSPORT_FILE}`
69
177
  end
70
178
  end
71
179
  end
@@ -0,0 +1,3 @@
1
+ pwcheck_method: auxprop
2
+ auxprop_plugin: sasldb
3
+ mech_list: plain