def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False): """ Main domain change tool Keyword argument: new_domain old_domain """ if not old_domain: with open('/etc/yunohost/current_host', 'r') as f: old_domain = f.readline().rstrip() if not new_domain: return {'current_main_domain': old_domain} if not new_domain: raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required')) if new_domain not in domain_list(auth)['domains']: domain_add(auth, new_domain) os.system('rm /etc/ssl/private/yunohost_key.pem') os.system('rm /etc/ssl/certs/yunohost_crt.pem') command_list = [ 'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain, 'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain, 'echo %s > /etc/yunohost/current_host' % new_domain, ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed')) if dyndns and len(new_domain.split('.')) >= 3: try: r = requests.get('https://dyndns.yunohost.org/domains') except requests.ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(new_domain.split('.')[1:]) if dyndomain in dyndomains: dyndns_subscribe(domain=new_domain) try: with open('/etc/yunohost/installed', 'r') as f: service_regen_conf() except IOError: pass logger.success(m18n.n('maindomain_changed'))
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False): """ Main domain change tool Keyword argument: new_domain old_domain """ if not old_domain: with open('/etc/yunohost/current_host', 'r') as f: old_domain = f.readline().rstrip() if not new_domain: return { 'current_main_domain': old_domain } if not new_domain: raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required')) if new_domain not in domain_list(auth)['domains']: domain_add(auth, new_domain) os.system('rm /etc/ssl/private/yunohost_key.pem') os.system('rm /etc/ssl/certs/yunohost_crt.pem') command_list = [ 'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain, 'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain, 'echo %s > /etc/yunohost/current_host' % new_domain, ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed')) if dyndns and len(new_domain.split('.')) >= 3: try: r = requests.get('https://dyndns.yunohost.org/domains') except requests.ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(new_domain.split('.')[1:]) if dyndomain in dyndomains: dyndns_subscribe(domain=new_domain) try: with open('/etc/yunohost/installed', 'r') as f: service_regen_conf() except IOError: pass logger.success(m18n.n('maindomain_changed'))
def domain_add(auth, domain, dyndns=False): """ Create a custom domain Keyword argument: domain -- Domain name to add dyndns -- Subscribe to DynDNS """ from yunohost.hook import hook_callback attr_dict = {'objectClass': ['mailDomain', 'top']} now = datetime.datetime.now() timestamp = str(now.year) + str(now.month) + str(now.day) if domain in domain_list(auth)['domains']: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) # DynDNS domain if dyndns: if len(domain.split('.')) < 3: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid')) from yunohost.dyndns import dyndns_subscribe try: r = requests.get('https://dyndns.yunohost.org/domains') except requests.ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(domain.split('.')[1:]) if dyndomain in dyndomains: if os.path.exists('/etc/cron.d/yunohost-dyndns'): raise MoulinetteError( errno.EPERM, m18n.n('domain_dyndns_already_subscribed')) dyndns_subscribe(domain=domain) else: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) try: yunohost.certificate._certificate_install_selfsigned([domain], False) try: auth.validate_uniqueness({'virtualdomain': domain}) except MoulinetteError: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) attr_dict['virtualdomain'] = domain if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed')) try: with open('/etc/yunohost/installed', 'r') as f: service_regen_conf( names=['nginx', 'metronome', 'dnsmasq', 'rmilter']) os.system('yunohost app ssowatconf > /dev/null 2>&1') except IOError: pass except: # Force domain removal silently try: domain_remove(auth, domain, True) except: pass raise hook_callback('post_domain_add', args=[domain]) logger.success(m18n.n('domain_created'))
def domain_add(operation_logger, domain, dyndns=False): """ Create a custom domain Keyword argument: domain -- Domain name to add dyndns -- Subscribe to DynDNS """ from yunohost.hook import hook_callback from yunohost.app import app_ssowatconf from yunohost.utils.ldap import _get_ldap_interface if domain.startswith("xmpp-upload."): raise YunohostError("domain_cannot_add_xmpp_upload") ldap = _get_ldap_interface() try: ldap.validate_uniqueness({"virtualdomain": domain}) except MoulinetteError: raise YunohostError("domain_exists") operation_logger.start() # Lower domain to avoid some edge cases issues # See: https://forum.yunohost.org/t/invalid-domain-causes-diagnosis-web-to-fail-fr-on-demand/11765 domain = domain.lower() # DynDNS domain if dyndns: # Do not allow to subscribe to multiple dyndns domains... if os.path.exists("/etc/cron.d/yunohost-dyndns"): raise YunohostError("domain_dyndns_already_subscribed") from yunohost.dyndns import dyndns_subscribe, _dyndns_provides # Check that this domain can effectively be provided by # dyndns.yunohost.org. (i.e. is it a nohost.me / noho.st) if not _dyndns_provides("dyndns.yunohost.org", domain): raise YunohostError("domain_dyndns_root_unknown") # Actually subscribe dyndns_subscribe(domain=domain) try: import yunohost.certificate yunohost.certificate._certificate_install_selfsigned([domain], False) attr_dict = { "objectClass": ["mailDomain", "top"], "virtualdomain": domain, } try: ldap.add("virtualdomain=%s,ou=domains" % domain, attr_dict) except Exception as e: raise YunohostError("domain_creation_failed", domain=domain, error=e) # Don't regen these conf if we're still in postinstall if os.path.exists("/etc/yunohost/installed"): # Sometime we have weird issues with the regenconf where some files # appears as manually modified even though they weren't touched ... # There are a few ideas why this happens (like backup/restore nginx # conf ... which we shouldnt do ...). This in turns creates funky # situation where the regenconf may refuse to re-create the conf # (when re-creating a domain..) # So here we force-clear the has out of the regenconf if it exists. # This is a pretty ad hoc solution and only applied to nginx # because it's one of the major service, but in the long term we # should identify the root of this bug... _force_clear_hashes(["/etc/nginx/conf.d/%s.conf" % domain]) regen_conf( names=["nginx", "metronome", "dnsmasq", "postfix", "rspamd"]) app_ssowatconf() except Exception: # Force domain removal silently try: domain_remove(domain, force=True) except Exception: pass raise hook_callback("post_domain_add", args=[domain]) logger.success(m18n.n("domain_created"))
def domain_add(auth, domain, dyndns=False): """ Create a custom domain Keyword argument: domain -- Domain name to add dyndns -- Subscribe to DynDNS """ from yunohost.hook import hook_callback attr_dict = { 'objectClass' : ['mailDomain', 'top'] } now = datetime.datetime.now() timestamp = str(now.year) + str(now.month) + str(now.day) if domain in domain_list(auth)['domains']: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) # DynDNS domain if dyndns: if len(domain.split('.')) < 3: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid')) from yunohost.dyndns import dyndns_subscribe try: r = requests.get('https://dyndns.yunohost.org/domains') except requests.ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(domain.split('.')[1:]) if dyndomain in dyndomains: if os.path.exists('/etc/cron.d/yunohost-dyndns'): raise MoulinetteError(errno.EPERM, m18n.n('domain_dyndns_already_subscribed')) dyndns_subscribe(domain=domain) else: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) try: # Commands ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA' ssl_domain_path = '/etc/yunohost/certs/%s' % domain with open('%s/serial' % ssl_dir, 'r') as f: serial = f.readline().rstrip() try: os.listdir(ssl_domain_path) except OSError: os.makedirs(ssl_domain_path) command_list = [ 'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path), 'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, ssl_domain_path), 'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path, 'cp %s/certs/yunohost_key.pem %s/key.pem' % (ssl_dir, ssl_domain_path), 'cp %s/newcerts/%s.pem %s/crt.pem' % (ssl_dir, serial, ssl_domain_path), 'chmod 755 %s' % ssl_domain_path, 'chmod 640 %s/key.pem' % ssl_domain_path, 'chmod 640 %s/crt.pem' % ssl_domain_path, 'chmod 600 %s/openssl.cnf' % ssl_domain_path, 'chown root:metronome %s/key.pem' % ssl_domain_path, 'chown root:metronome %s/crt.pem' % ssl_domain_path, 'cat %s/ca.pem >> %s/crt.pem' % (ssl_domain_path, ssl_domain_path) ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EIO, m18n.n('domain_cert_gen_failed')) try: auth.validate_uniqueness({ 'virtualdomain': domain }) except MoulinetteError: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) attr_dict['virtualdomain'] = domain if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed')) try: with open('/etc/yunohost/installed', 'r') as f: service_regen_conf(names=[ 'nginx', 'metronome', 'dnsmasq', 'rmilter']) os.system('yunohost app ssowatconf > /dev/null 2>&1') except IOError: pass except: # Force domain removal silently try: domain_remove(auth, domain, True) except: pass raise hook_callback('post_domain_add', args=[domain]) logger.success(m18n.n('domain_created'))
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False): """ Main domain change tool Keyword argument: new_domain old_domain """ from yunohost.domain import domain_add from yunohost.dyndns import dyndns_subscribe if not old_domain: with open('/etc/yunohost/current_host', 'r') as f: old_domain = f.readline().rstrip() if not new_domain: return { 'current_main_domain': old_domain } config_files = [ '/etc/postfix/main.cf', '/etc/metronome/metronome.cfg.lua', '/etc/dovecot/dovecot.conf', '/usr/share/yunohost/yunohost-config/others/startup', '/home/yunohost.backup/tahoe/tahoe.cfg', '/etc/amavis/conf.d/05-node_id', '/etc/amavis/conf.d/50-user' ] config_dir = [] for dir in config_dir: for file in os.listdir(dir): config_files.append(dir + '/' + file) for file in config_files: with open(file, "r") as sources: lines = sources.readlines() with open(file, "w") as sources: for line in lines: sources.write(re.sub(r''+ old_domain +'', new_domain, line)) domain_add(auth, [new_domain], main=True) os.system('rm /etc/ssl/private/yunohost_key.pem') os.system('rm /etc/ssl/certs/yunohost_crt.pem') command_list = [ 'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain, 'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain, 'echo %s > /etc/yunohost/current_host' % new_domain, 'service metronome restart', 'service postfix restart', 'service dovecot restart', 'service amavis restart', 'service nginx restart', ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed')) if dyndns: dyndns_subscribe(domain=new_domain) elif len(new_domain.split('.')) >= 3: try: r = requests.get('http://dyndns.yunohost.org/domains') except ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(new_domain.split('.')[1:]) if dyndomain in dyndomains: dyndns_subscribe(domain=new_domain) msignals.display(m18n.n('maindomain_changed'), 'success')
def domain_add(auth, domain, dyndns=False): """ Create a custom domain Keyword argument: domain -- Domain name to add dyndns -- Subscribe to DynDNS """ from yunohost.hook import hook_callback attr_dict = {'objectClass': ['mailDomain', 'top']} now = datetime.datetime.now() timestamp = str(now.year) + str(now.month) + str(now.day) if domain in domain_list(auth)['domains']: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) # DynDNS domain if dyndns: if len(domain.split('.')) < 3: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid')) from yunohost.dyndns import dyndns_subscribe try: r = requests.get('https://dyndns.yunohost.org/domains') except requests.ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(domain.split('.')[1:]) if dyndomain in dyndomains: if os.path.exists('/etc/cron.d/yunohost-dyndns'): raise MoulinetteError( errno.EPERM, m18n.n('domain_dyndns_already_subscribed')) dyndns_subscribe(domain=domain) else: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) try: # Commands ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA' ssl_domain_path = '/etc/yunohost/certs/%s' % domain with open('%s/serial' % ssl_dir, 'r') as f: serial = f.readline().rstrip() try: os.listdir(ssl_domain_path) except OSError: os.makedirs(ssl_domain_path) command_list = [ 'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path), 'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, ssl_domain_path), 'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path, 'cp %s/certs/yunohost_key.pem %s/key.pem' % (ssl_dir, ssl_domain_path), 'cp %s/newcerts/%s.pem %s/crt.pem' % (ssl_dir, serial, ssl_domain_path), 'chmod 755 %s' % ssl_domain_path, 'chmod 640 %s/key.pem' % ssl_domain_path, 'chmod 640 %s/crt.pem' % ssl_domain_path, 'chmod 600 %s/openssl.cnf' % ssl_domain_path, 'chown root:metronome %s/key.pem' % ssl_domain_path, 'chown root:metronome %s/crt.pem' % ssl_domain_path, 'cat %s/ca.pem >> %s/crt.pem' % (ssl_domain_path, ssl_domain_path) ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EIO, m18n.n('domain_cert_gen_failed')) try: auth.validate_uniqueness({'virtualdomain': domain}) except MoulinetteError: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) attr_dict['virtualdomain'] = domain if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed')) try: with open('/etc/yunohost/installed', 'r') as f: service_regen_conf( names=['nginx', 'metronome', 'dnsmasq', 'rmilter']) os.system('yunohost app ssowatconf > /dev/null 2>&1') except IOError: pass except: # Force domain removal silently try: domain_remove(auth, domain, True) except: pass raise hook_callback('post_domain_add', args=[domain]) logger.success(m18n.n('domain_created'))
def domain_add(auth, domain, dyndns=False): """ Create a custom domain Keyword argument: domain -- Domain name to add dyndns -- Subscribe to DynDNS """ attr_dict = { 'objectClass' : ['mailDomain', 'top'] } try: ip = str(urlopen('http://ip.yunohost.org').read()) except IOError: ip = "127.0.0.1" now = datetime.datetime.now() timestamp = str(now.year) + str(now.month) + str(now.day) if domain in domain_list(auth)['domains']: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) # DynDNS domain if dyndns: if len(domain.split('.')) < 3: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid')) import requests from yunohost.dyndns import dyndns_subscribe try: r = requests.get('https://dyndns.yunohost.org/domains') except ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(domain.split('.')[1:]) if dyndomain in dyndomains: if os.path.exists('/etc/cron.d/yunohost-dyndns'): raise MoulinetteError(errno.EPERM, m18n.n('domain_dyndns_already_subscribed')) dyndns_subscribe(domain=domain) else: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) try: # Commands ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA' ssl_domain_path = '/etc/yunohost/certs/%s' % domain with open('%s/serial' % ssl_dir, 'r') as f: serial = f.readline().rstrip() try: os.listdir(ssl_domain_path) except OSError: os.makedirs(ssl_domain_path) command_list = [ 'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path), 'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, ssl_domain_path), 'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path, 'cp %s/certs/yunohost_key.pem %s/key.pem' % (ssl_dir, ssl_domain_path), 'cp %s/newcerts/%s.pem %s/crt.pem' % (ssl_dir, serial, ssl_domain_path), 'chmod 755 %s' % ssl_domain_path, 'chmod 640 %s/key.pem' % ssl_domain_path, 'chmod 640 %s/crt.pem' % ssl_domain_path, 'chmod 600 %s/openssl.cnf' % ssl_domain_path, 'chown root:metronome %s/key.pem' % ssl_domain_path, 'chown root:metronome %s/crt.pem' % ssl_domain_path ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EIO, m18n.n('domain_cert_gen_failed')) try: auth.validate_uniqueness({ 'virtualdomain': domain }) except MoulinetteError: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) attr_dict['virtualdomain'] = domain dnsmasq_config_path='/etc/dnsmasq.d' try: os.listdir(dnsmasq_config_path) except OSError: msignals.display(m18n.n('dnsmasq_isnt_installed'), 'warning') os.makedirs(dnsmasq_config_path) try: with open('%s/%s' % (dnsmasq_config_path, domain)) as f: pass except IOError as e: zone_lines = [ 'address=/%s/%s' % (domain, ip), 'txt-record=%s,"v=spf1 mx a -all"' % domain, 'mx-host=%s,%s,5' % (domain, domain), 'srv-host=_xmpp-client._tcp.%s,%s,5222,0,5' % (domain, domain), 'srv-host=_xmpp-server._tcp.%s,%s,5269,0,5' % (domain, domain), 'srv-host=_jabber._tcp.%s,%s,5269,0,5' % (domain, domain), ] with open('%s/%s' % (dnsmasq_config_path, domain), 'w') as zone: for line in zone_lines: zone.write(line + '\n') os.system('service dnsmasq restart') else: msignals.display(m18n.n('domain_zone_exists'), 'warning') # XMPP try: with open('/etc/metronome/conf.d/%s.cfg.lua' % domain) as f: pass except IOError as e: conf_lines = [ 'VirtualHost "%s"' % domain, ' ssl = {', ' key = "%s/key.pem";' % ssl_domain_path, ' certificate = "%s/crt.pem";' % ssl_domain_path, ' }', ' authentication = "ldap2"', ' ldap = {', ' hostname = "localhost",', ' user = {', ' basedn = "ou=users,dc=yunohost,dc=org",', ' filter = "(&(objectClass=posixAccount)(mail=*@%s))",' % domain, ' usernamefield = "mail",', ' namefield = "cn",', ' },', ' }', ] with open('/etc/metronome/conf.d/%s.cfg.lua' % domain, 'w') as conf: for line in conf_lines: conf.write(line + '\n') os.system('mkdir -p /var/lib/metronome/%s/pep' % domain.replace('.', '%2e')) os.system('chown -R metronome: /var/lib/metronome/') os.system('chown -R metronome: /etc/metronome/conf.d/') os.system('service metronome restart') # Nginx os.system('cp /usr/share/yunohost/yunohost-config/nginx/template.conf /etc/nginx/conf.d/%s.conf' % domain) os.system('mkdir /etc/nginx/conf.d/%s.d/' % domain) os.system('sed -i s/yunohost.org/%s/g /etc/nginx/conf.d/%s.conf' % (domain, domain)) os.system('service nginx reload') if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed')) os.system('yunohost app ssowatconf > /dev/null 2>&1') except: # Force domain removal silently try: domain_remove(auth, domain, True) except: pass raise msignals.display(m18n.n('domain_created'), 'success')
def domain_add(auth, domains, main=False, dyndns=False): """ Create a custom domain Keyword argument: domains -- Domain name to add main -- Is the main domain dyndns -- Subscribe to DynDNS """ attr_dict = { 'objectClass' : ['mailDomain', 'top'] } try: ip = str(urlopen('http://ip.yunohost.org').read()) except IOError: ip = "127.0.0.1" now = datetime.datetime.now() timestamp = str(now.year) + str(now.month) + str(now.day) result = [] if not isinstance(domains, list): domains = [ domains ] for domain in domains: if domain in domain_list(auth)['domains']: continue # DynDNS domain if dyndns: if len(domain.split('.')) < 3: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid')) import requests from yunohost.dyndns import dyndns_subscribe try: r = requests.get('http://dyndns.yunohost.org/domains') except ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(domain.split('.')[1:]) if dyndomain in dyndomains: if os.path.exists('/etc/cron.d/yunohost-dyndns'): raise MoulinetteError(errno.EPERM, m18n.n('domain_dyndns_already_subscribed')) dyndns_subscribe(domain=domain) else: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) # Commands ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA' ssl_domain_path = '/etc/yunohost/certs/%s' % domain with open('%s/serial' % ssl_dir, 'r') as f: serial = f.readline().rstrip() try: os.listdir(ssl_domain_path) except OSError: os.makedirs(ssl_domain_path) command_list = [ 'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path), 'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, ssl_domain_path), 'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path, 'cp %s/certs/yunohost_key.pem %s/key.pem' % (ssl_dir, ssl_domain_path), 'cp %s/newcerts/%s.pem %s/crt.pem' % (ssl_dir, serial, ssl_domain_path), 'chmod 755 %s' % ssl_domain_path, 'chmod 640 %s/key.pem' % ssl_domain_path, 'chmod 640 %s/crt.pem' % ssl_domain_path, 'chmod 600 %s/openssl.cnf' % ssl_domain_path, 'chown root:metronome %s/key.pem' % ssl_domain_path, 'chown root:metronome %s/crt.pem' % ssl_domain_path ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EIO, m18n.n('domain_cert_gen_failed')) try: auth.validate_uniqueness({ 'virtualdomain': domain }) except MoulinetteError: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) attr_dict['virtualdomain'] = domain try: with open('/var/lib/bind/%s.zone' % domain) as f: pass except IOError as e: zone_lines = [ '$TTL 38400', '%s. IN SOA ns.%s. root.%s. %s 10800 3600 604800 38400' % (domain, domain, domain, timestamp), '%s. IN NS ns.%s.' % (domain, domain), '%s. IN A %s' % (domain, ip), '%s. IN MX 5 %s.' % (domain, domain), '%s. IN TXT "v=spf1 mx a -all"' % domain, 'ns.%s. IN A %s' % (domain, ip), '_xmpp-client._tcp.%s. IN SRV 0 5 5222 %s.' % (domain, domain), '_xmpp-server._tcp.%s. IN SRV 0 5 5269 %s.' % (domain, domain), '_jabber._tcp.%s. IN SRV 0 5 5269 %s.' % (domain, domain), ] if main: zone_lines.extend([ 'pubsub.%s. IN A %s' % (domain, ip), 'muc.%s. IN A %s' % (domain, ip), 'vjud.%s. IN A %s' % (domain, ip) ]) with open('/var/lib/bind/%s.zone' % domain, 'w') as zone: for line in zone_lines: zone.write(line + '\n') os.system('chown bind /var/lib/bind/%s.zone' % domain) else: raise MoulinetteError(errno.EEXIST, m18n.n('domain_zone_exists')) conf_lines = [ 'zone "%s" {' % domain, ' type master;', ' file "/var/lib/bind/%s.zone";' % domain, ' allow-transfer {', ' 127.0.0.1;', ' localnets;', ' };', '};' ] with open('/etc/bind/named.conf.local', 'a') as conf: for line in conf_lines: conf.write(line + '\n') os.system('service bind9 reload') # XMPP try: with open('/etc/metronome/conf.d/%s.cfg.lua' % domain) as f: pass except IOError as e: conf_lines = [ 'VirtualHost "%s"' % domain, ' ssl = {', ' key = "%s/key.pem";' % ssl_domain_path, ' certificate = "%s/crt.pem";' % ssl_domain_path, ' }', ' authentication = "ldap2"', ' ldap = {', ' hostname = "localhost",', ' user = {', ' basedn = "ou=users,dc=yunohost,dc=org",', ' filter = "(&(objectClass=posixAccount)(mail=*@%s))",' % domain, ' usernamefield = "mail",', ' namefield = "cn",', ' },', ' }', ] with open('/etc/metronome/conf.d/%s.cfg.lua' % domain, 'w') as conf: for line in conf_lines: conf.write(line + '\n') os.system('mkdir -p /var/lib/metronome/%s/pep' % domain.replace('.', '%2e')) os.system('chown -R metronome: /var/lib/metronome/') os.system('chown -R metronome: /etc/metronome/conf.d/') os.system('service metronome restart') # Nginx os.system('cp /usr/share/yunohost/yunohost-config/nginx/template.conf /etc/nginx/conf.d/%s.conf' % domain) os.system('mkdir /etc/nginx/conf.d/%s.d/' % domain) os.system('sed -i s/yunohost.org/%s/g /etc/nginx/conf.d/%s.conf' % (domain, domain)) os.system('service nginx reload') if auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): result.append(domain) continue else: raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed')) os.system('yunohost app ssowatconf > /dev/null 2>&1') msignals.display(m18n.n('domain_created'), 'success') return { 'domains': result }
def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False): """ Main domain change tool Keyword argument: new_domain old_domain """ from yunohost.domain import domain_add, domain_list from yunohost.dyndns import dyndns_subscribe if not old_domain: with open('/etc/yunohost/current_host', 'r') as f: old_domain = f.readline().rstrip() if not new_domain: return { 'current_main_domain': old_domain } if not new_domain: raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required')) if new_domain not in domain_list(auth)['domains']: domain_add(auth, new_domain) config_files = [ '/etc/postfix/main.cf', '/etc/metronome/metronome.cfg.lua', '/etc/dovecot/dovecot.conf', '/usr/share/yunohost/yunohost-config/others/startup', '/etc/amavis/conf.d/05-node_id', '/etc/amavis/conf.d/50-user' ] config_dir = [] for dir in config_dir: for file in os.listdir(dir): config_files.append(dir + '/' + file) for file in config_files: with open(file, "r") as sources: lines = sources.readlines() with open(file, "w") as sources: for line in lines: sources.write(re.sub(r''+ old_domain +'', new_domain, line)) ## Update DNS zone file for old and new domains main_subdomains = ['pubsub', 'muc', 'vjud'] try: with open('/var/lib/bind/%s.zone' % old_domain, 'r') as f: old_zone = f.read() except IOError: pass else: # Remove unneeded subdomains entries for sub in main_subdomains: old_zone = re.sub( r'^({sub}.{domain}.|{sub})[\ \t]+(IN).*$[\n]?'.format( sub=sub, domain=old_domain), '', old_zone, 1, re.MULTILINE) with open('/var/lib/bind/%s.zone' % old_domain, 'w') as f: f.write(old_zone) try: with open('/var/lib/bind/%s.zone' % new_domain, 'r') as f: new_zone = f.read() except IOError: msignals.display(m18n.n('domain_zone_not_found', new_domain), 'warning') else: # Add main subdomains entries for sub in main_subdomains: new_zone += '{sub} IN CNAME {domain}.\n'.format( sub=sub, domain=new_domain) with open('/var/lib/bind/%s.zone' % new_domain, 'w') as f: f.write(new_zone) os.system('rm /etc/ssl/private/yunohost_key.pem') os.system('rm /etc/ssl/certs/yunohost_crt.pem') command_list = [ 'rm -f /etc/nginx/conf.d/%s.d/yunohost_local.conf' % old_domain, 'cp /usr/share/yunohost/yunohost-config/nginx/yunohost_local.conf /etc/nginx/conf.d/%s.d/' % new_domain, 'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain, 'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain, 'echo %s > /etc/yunohost/current_host' % new_domain, 'service metronome restart', 'service postfix restart', 'service dovecot restart', 'service amavis restart', 'service nginx restart', ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EPERM, m18n.n('maindomain_change_failed')) if dyndns and len(new_domain.split('.')) >= 3: try: r = requests.get('https://dyndns.yunohost.org/domains') except ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(new_domain.split('.')[1:]) if dyndomain in dyndomains: dyndns_subscribe(domain=new_domain) msignals.display(m18n.n('maindomain_changed'), 'success')
def domain_add(auth, domain, dyndns=False): """ Create a custom domain Keyword argument: domain -- Domain name to add dyndns -- Subscribe to DynDNS """ attr_dict = {'objectClass': ['mailDomain', 'top']} try: ip = str(urlopen('http://ip.yunohost.org').read()) except IOError: ip = "127.0.0.1" now = datetime.datetime.now() timestamp = str(now.year) + str(now.month) + str(now.day) if domain in domain_list(auth)['domains']: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) # DynDNS domain if dyndns: if len(domain.split('.')) < 3: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid')) import requests from yunohost.dyndns import dyndns_subscribe try: r = requests.get('https://dyndns.yunohost.org/domains') except ConnectionError: pass else: dyndomains = json.loads(r.text) dyndomain = '.'.join(domain.split('.')[1:]) if dyndomain in dyndomains: if os.path.exists('/etc/cron.d/yunohost-dyndns'): raise MoulinetteError( errno.EPERM, m18n.n('domain_dyndns_already_subscribed')) dyndns_subscribe(domain=domain) else: raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_root_unknown')) try: # Commands ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA' ssl_domain_path = '/etc/yunohost/certs/%s' % domain with open('%s/serial' % ssl_dir, 'r') as f: serial = f.readline().rstrip() try: os.listdir(ssl_domain_path) except OSError: os.makedirs(ssl_domain_path) command_list = [ 'cp %s/openssl.cnf %s' % (ssl_dir, ssl_domain_path), 'sed -i "s/yunohost.org/%s/g" %s/openssl.cnf' % (domain, ssl_domain_path), 'openssl req -new -config %s/openssl.cnf -days 3650 -out %s/certs/yunohost_csr.pem -keyout %s/certs/yunohost_key.pem -nodes -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'openssl ca -config %s/openssl.cnf -days 3650 -in %s/certs/yunohost_csr.pem -out %s/certs/yunohost_crt.pem -batch' % (ssl_domain_path, ssl_dir, ssl_dir), 'ln -s /etc/ssl/certs/ca-yunohost_crt.pem %s/ca.pem' % ssl_domain_path, 'cp %s/certs/yunohost_key.pem %s/key.pem' % (ssl_dir, ssl_domain_path), 'cp %s/newcerts/%s.pem %s/crt.pem' % (ssl_dir, serial, ssl_domain_path), 'chmod 755 %s' % ssl_domain_path, 'chmod 640 %s/key.pem' % ssl_domain_path, 'chmod 640 %s/crt.pem' % ssl_domain_path, 'chmod 600 %s/openssl.cnf' % ssl_domain_path, 'chown root:metronome %s/key.pem' % ssl_domain_path, 'chown root:metronome %s/crt.pem' % ssl_domain_path ] for command in command_list: if os.system(command) != 0: raise MoulinetteError(errno.EIO, m18n.n('domain_cert_gen_failed')) try: auth.validate_uniqueness({'virtualdomain': domain}) except MoulinetteError: raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists')) attr_dict['virtualdomain'] = domain dnsmasq_config_path = '/etc/dnsmasq.d' try: os.listdir(dnsmasq_config_path) except OSError: msignals.display(m18n.n('dnsmasq_isnt_installed'), 'warning') os.makedirs(dnsmasq_config_path) try: with open('%s/%s' % (dnsmasq_config_path, domain)) as f: pass except IOError as e: zone_lines = [ 'address=/%s/%s' % (domain, ip), 'txt-record=%s,"v=spf1 mx a -all"' % domain, 'mx-host=%s,%s,5' % (domain, domain), 'srv-host=_xmpp-client._tcp.%s,%s,5222,0,5' % (domain, domain), 'srv-host=_xmpp-server._tcp.%s,%s,5269,0,5' % (domain, domain), 'srv-host=_jabber._tcp.%s,%s,5269,0,5' % (domain, domain), ] with open('%s/%s' % (dnsmasq_config_path, domain), 'w') as zone: for line in zone_lines: zone.write(line + '\n') os.system('service dnsmasq restart') else: msignals.display(m18n.n('domain_zone_exists'), 'warning') # XMPP try: with open('/etc/metronome/conf.d/%s.cfg.lua' % domain) as f: pass except IOError as e: conf_lines = [ 'VirtualHost "%s"' % domain, ' ssl = {', ' key = "%s/key.pem";' % ssl_domain_path, ' certificate = "%s/crt.pem";' % ssl_domain_path, ' }', ' authentication = "ldap2"', ' ldap = {', ' hostname = "localhost",', ' user = {', ' basedn = "ou=users,dc=yunohost,dc=org",', ' filter = "(&(objectClass=posixAccount)(mail=*@%s))",' % domain, ' usernamefield = "mail",', ' namefield = "cn",', ' },', ' }', ] with open('/etc/metronome/conf.d/%s.cfg.lua' % domain, 'w') as conf: for line in conf_lines: conf.write(line + '\n') os.system('mkdir -p /var/lib/metronome/%s/pep' % domain.replace('.', '%2e')) os.system('chown -R metronome: /var/lib/metronome/') os.system('chown -R metronome: /etc/metronome/conf.d/') os.system('service metronome restart') # Nginx os.system( 'cp /usr/share/yunohost/yunohost-config/nginx/template.conf /etc/nginx/conf.d/%s.conf' % domain) os.system('mkdir /etc/nginx/conf.d/%s.d/' % domain) os.system('sed -i s/yunohost.org/%s/g /etc/nginx/conf.d/%s.conf' % (domain, domain)) os.system('service nginx reload') if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): raise MoulinetteError(errno.EIO, m18n.n('domain_creation_failed')) os.system('yunohost app ssowatconf > /dev/null 2>&1') except: # Force domain removal silently try: domain_remove(auth, domain, True) except: pass raise msignals.display(m18n.n('domain_created'), 'success')