ConfigLMM 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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