def install_check(installer): options = installer dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file http_pkcs12_file = installer._http_pkcs12_file pkinit_pkcs12_file = installer._pkinit_pkcs12_file dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info http_pkcs12_info = installer._http_pkcs12_info pkinit_pkcs12_info = installer._pkinit_pkcs12_info external_cert_file = installer._external_cert_file external_ca_file = installer._external_ca_file http_ca_cert = installer._ca_cert tasks.check_ipv6_stack_enabled() tasks.check_selinux_status() if options.master_password: msg = ("WARNING:\noption '-P/--master-password' is deprecated. " "KDC master password of sufficient strength is autogenerated " "during IPA server installation and should not be set " "manually.") print(textwrap.fill(msg, width=79, replace_whitespace=False)) installer._installation_cleanup = True print("\nThe log file for this installation can be found in " "/var/log/ipaserver-install.log") if (not options.external_ca and not options.external_cert_files and is_ipa_configured()): installer._installation_cleanup = False raise ScriptError( "IPA server is already configured on this system.\n" "If you want to reinstall the IPA server, please uninstall " "it first using 'ipa-server-install --uninstall'.") client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if client_fstore.has_files(): installer._installation_cleanup = False raise ScriptError( "IPA client is already configured on this system.\n" "Please uninstall it before configuring the IPA server, " "using 'ipa-client-install --uninstall'") fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH) sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH) # This will override any settings passed in on the cmdline if ipautil.file_exists(paths.ROOT_IPA_CACHE): if options.dm_password is not None: dm_password = options.dm_password else: dm_password = read_password("Directory Manager", confirm=False) if dm_password is None: raise ScriptError("Directory Manager password required") try: cache_vars = read_cache(dm_password) options.__dict__.update(cache_vars) if cache_vars.get('external_ca', False): options.external_ca = False options.interactive = False except Exception as e: raise ScriptError("Cannot process the cache file: %s" % str(e)) # We only set up the CA if the PKCS#12 options are not given. if options.dirsrv_cert_files: setup_ca = False else: setup_ca = True options.setup_ca = setup_ca if not setup_ca and options.ca_subject: raise ScriptError( "--ca-subject cannot be used with CA-less installation") if not setup_ca and options.subject_base: raise ScriptError( "--subject-base cannot be used with CA-less installation") if not setup_ca and options.setup_kra: raise ScriptError( "--setup-kra cannot be used with CA-less installation") print("=======================================" "=======================================") print("This program will set up the FreeIPA Server.") print("") print("This includes:") if setup_ca: print(" * Configure a stand-alone CA (dogtag) for certificate " "management") if not options.no_ntp: print(" * Configure the Network Time Daemon (ntpd)") print(" * Create and configure an instance of Directory Server") print(" * Create and configure a Kerberos Key Distribution Center (KDC)") print(" * Configure Apache (httpd)") if options.setup_kra: print(" * Configure KRA (dogtag) for secret management") if options.setup_dns: print(" * Configure DNS (bind)") if options.setup_adtrust: print(" * Configure Samba (smb) and winbind for managing AD trusts") if not options.no_pkinit: print(" * Configure the KDC to enable PKINIT") if options.no_ntp: print("") print("Excluded by options:") print(" * Configure the Network Time Daemon (ntpd)") if installer.interactive: print("") print("To accept the default shown in brackets, press the Enter key.") print("") if not options.external_cert_files: # Make sure the 389-ds ports are available check_dirsrv(not installer.interactive) if not options.no_ntp: try: ipaclient.install.ntpconf.check_timedate_services() except ipaclient.install.ntpconf.NTPConflictingService as e: print( ("WARNING: conflicting time&date synchronization service '%s'" " will be disabled" % e.conflicting_service)) print("in favor of ntpd") print("") except ipaclient.install.ntpconf.NTPConfigurationError: pass # Check to see if httpd is already configured to listen on 443 if httpinstance.httpd_443_configured(): raise ScriptError("Aborting installation") if not options.setup_dns and installer.interactive: if ipautil.user_input( "Do you want to configure integrated DNS " "(BIND)?", False): options.setup_dns = True print("") # check bind packages are installed if options.setup_dns: # Don't require an external DNS to say who we are if we are # setting up a local DNS server. options.no_host_dns = True # check the hostname is correctly configured, it must be as the kldap # utilities just use the hostname as returned by getaddrinfo to set # up some of the standard entries if options.host_name: host_default = options.host_name else: host_default = get_fqdn() try: if not installer.interactive or options.host_name: verify_fqdn(host_default, options.no_host_dns) host_name = host_default else: host_name = read_host_name(host_default, options.no_host_dns) except BadHostError as e: raise ScriptError(e) host_name = host_name.lower() root_logger.debug("will use host_name: %s\n" % host_name) if not options.domain_name: domain_name = read_domain_name(host_name[host_name.find(".") + 1:], not installer.interactive) root_logger.debug("read domain_name: %s\n" % domain_name) try: validate_domain_name(domain_name) except ValueError as e: raise ScriptError("Invalid domain name: %s" % unicode(e)) else: domain_name = options.domain_name domain_name = domain_name.lower() if not options.realm_name: realm_name = read_realm_name(domain_name, not installer.interactive) root_logger.debug("read realm_name: %s\n" % realm_name) else: realm_name = options.realm_name.upper() if not options.subject_base: options.subject_base = installutils.default_subject_base(realm_name) if not options.ca_subject: options.ca_subject = \ installutils.default_ca_subject_dn(options.subject_base) if options.http_cert_files: if options.http_pin is None: options.http_pin = installutils.read_password( "Enter Apache Server private key unlock", confirm=False, validate=False, retry=False) if options.http_pin is None: raise ScriptError( "Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12( cert_files=options.http_cert_files, key_password=options.http_pin, key_nickname=options.http_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) http_pkcs12_info = (http_pkcs12_file.name, http_pin) if options.dirsrv_cert_files: if options.dirsrv_pin is None: options.dirsrv_pin = read_password( "Enter Directory Server private key unlock", confirm=False, validate=False, retry=False) if options.dirsrv_pin is None: raise ScriptError( "Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12( cert_files=options.dirsrv_cert_files, key_password=options.dirsrv_pin, key_nickname=options.dirsrv_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin) if options.pkinit_cert_files: if options.pkinit_pin is None: options.pkinit_pin = read_password( "Enter Kerberos KDC private key unlock", confirm=False, validate=False, retry=False) if options.pkinit_pin is None: raise ScriptError( "Kerberos KDC private key unlock password required") pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12( cert_files=options.pkinit_cert_files, key_password=options.pkinit_pin, key_nickname=options.pkinit_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin) if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): raise ScriptError( "Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate") if not options.dm_password: dm_password = read_dm_password() if dm_password is None: raise ScriptError("Directory Manager password required") else: dm_password = options.dm_password if not options.master_password: master_password = ipa_generate_password() else: master_password = options.master_password if not options.admin_password: admin_password = read_admin_password() if admin_password is None: raise ScriptError("IPA admin password required") else: admin_password = options.admin_password # Configuration for ipalib, we will bootstrap and finalize later, after # we are sure we have the configuration file ready. cfg = dict( context='installer', confdir=paths.ETC_IPA, in_server=True, # make sure host name specified by user is used instead of default host=host_name, ) if setup_ca: # we have an IPA-integrated CA cfg['ca_host'] = host_name # Create the management framework config file and finalize api target_fname = paths.IPA_DEFAULT_CONF fd = open(target_fname, "w") fd.write("[global]\n") fd.write("host=%s\n" % host_name) fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name)) fd.write("realm=%s\n" % realm_name) fd.write("domain=%s\n" % domain_name) fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name)) fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % installutils.realm_to_serverid(realm_name)) if setup_ca: fd.write("enable_ra=True\n") fd.write("ra_plugin=dogtag\n") fd.write("dogtag_version=10\n") else: fd.write("enable_ra=False\n") fd.write("ra_plugin=none\n") fd.write("mode=production\n") fd.close() # Must be readable for everyone os.chmod(target_fname, 0o644) api.bootstrap(**cfg) api.finalize() if setup_ca: ca.install_check(False, None, options) if options.setup_kra: kra.install_check(api, None, options) if options.setup_dns: dns.install_check(False, api, False, options, host_name) ip_addresses = dns.ip_addresses else: ip_addresses = get_server_ip_address(host_name, not installer.interactive, False, options.ip_addresses) # check addresses here, dns module is doing own check network_ip_address_warning(ip_addresses) broadcast_ip_address_warning(ip_addresses) if options.setup_adtrust: adtrust.install_check(False, options, api) # installer needs to update hosts file when DNS subsystem will be # installed or custom addresses are used if options.ip_addresses or options.setup_dns: installer._update_hosts_file = True print() print("The IPA Master Server will be configured with:") print("Hostname: %s" % host_name) print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses)) print("Domain name: %s" % domain_name) print("Realm name: %s" % realm_name) print() if options.setup_dns: print("BIND DNS server will be configured to serve IPA domain with:") print("Forwarders: %s" % ("No forwarders" if not options.forwarders else ", ".join( [str(ip) for ip in options.forwarders]))) print('Forward policy: %s' % options.forward_policy) print("Reverse zone(s): %s" % ("No reverse zone" if options.no_reverse or not dns.reverse_zones else ", ".join(str(rz) for rz in dns.reverse_zones))) print() if not options.setup_adtrust: # If domain name and realm does not match, IPA server will not be able # to estabilish trust with Active Directory. Print big fat warning. realm_not_matching_domain = (domain_name.upper() != realm_name) if realm_not_matching_domain: print("WARNING: Realm name does not match the domain name.\n" "You will not be able to estabilish trusts with Active " "Directory unless\nthe realm name of the IPA server matches " "its domain name.\n\n") if installer.interactive and not user_input( "Continue to configure the system with these values?", False): raise ScriptError("Installation aborted") options.realm_name = realm_name options.domain_name = domain_name options.dm_password = dm_password options.master_password = master_password options.admin_password = admin_password options._host_name_overridden = bool(options.host_name) options.host_name = host_name options.ip_addresses = ip_addresses installer._fstore = fstore installer._sstore = sstore installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file installer._http_pkcs12_file = http_pkcs12_file installer._pkinit_pkcs12_file = pkinit_pkcs12_file installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info installer._http_pkcs12_info = http_pkcs12_info installer._pkinit_pkcs12_info = pkinit_pkcs12_info installer._external_cert_file = external_cert_file installer._external_ca_file = external_ca_file installer._ca_cert = http_ca_cert
def install_check(standalone, api, replica, options, hostname): global ip_addresses global reverse_zones fstore = sysrestore.FileStore(paths.SYSRESTORE) if not ipautil.file_exists(paths.IPA_DNS_INSTALL): raise RuntimeError("Integrated DNS requires '%s' package" % constants.IPA_DNS_PACKAGE_NAME) # when installing first DNS instance we need to check zone overlap if replica or standalone: already_enabled = api.Command.dns_is_enabled()['result'] else: already_enabled = False if not already_enabled: domain = dnsutil.DNSName(util.normalize_zone(api.env.domain)) print("Checking DNS domain %s, please wait ..." % domain) try: dnsutil.check_zone_overlap(domain, raise_on_error=False) except ValueError as e: if options.force or options.allow_zone_overlap: root_logger.warning("%s Please make sure that the domain is " "properly delegated to this IPA server.", e.message) else: raise e for reverse_zone in options.reverse_zones: try: dnsutil.check_zone_overlap(reverse_zone) except ValueError as e: if options.force or options.allow_zone_overlap: root_logger.warning(e.message) else: raise e if standalone: print("==============================================================================") print("This program will setup DNS for the FreeIPA Server.") print("") print("This includes:") print(" * Configure DNS (bind)") print(" * Configure SoftHSM (required by DNSSEC)") print(" * Configure ipa-dnskeysyncd (required by DNSSEC)") if options.dnssec_master: print(" * Configure ipa-ods-exporter (required by DNSSEC key master)") print(" * Configure OpenDNSSEC (required by DNSSEC key master)") print(" * Generate DNSSEC master key (required by DNSSEC key master)") elif options.disable_dnssec_master: print(" * Unconfigure ipa-ods-exporter") print(" * Unconfigure OpenDNSSEC") print("") print("No new zones will be signed without DNSSEC key master IPA server.") print("") print(("Please copy file from %s after uninstallation. This file is needed " "on new DNSSEC key " % paths.IPA_KASP_DB_BACKUP)) print("master server") print("") print("NOTE: DNSSEC zone signing is not enabled by default") print("") if options.dnssec_master: print("Plan carefully, replacing DNSSEC key master is not recommended") print("") print("") print("To accept the default shown in brackets, press the Enter key.") print("") if (options.dnssec_master and not options.unattended and not ipautil.user_input( "Do you want to setup this IPA server as DNSSEC key master?", False)): sys.exit("Aborted") elif (options.disable_dnssec_master and not options.unattended and not ipautil.user_input( "Do you want to disable current DNSSEC key master?", False)): sys.exit("Aborted") if options.disable_dnssec_master: _is_master() if options.disable_dnssec_master or options.dnssec_master: dnssec_zones = _find_dnssec_enabled_zones(api.Backend.ldap2) if options.disable_dnssec_master: if dnssec_zones and not options.force: raise RuntimeError( "Cannot disable DNSSEC key master, DNSSEC signing is still " "enabled for following zone(s):\n" "%s\n" "It is possible to move DNSSEC key master role to a different " "server by using --force option to skip this check.\n\n" "WARNING: You have to immediatelly copy kasp.db file to a new " "server and run command 'ipa-dns-install --dnssec-master " "--kasp-db'.\n" "Your DNS zones will become unavailable if you " "do not reinstall the DNSSEC key master role immediatelly." % ", ".join([str(zone) for zone in dnssec_zones])) elif options.dnssec_master: ods = opendnssecinstance.OpenDNSSECInstance(fstore) ods.realm = api.env.realm dnssec_masters = ods.get_masters() # we can reinstall current server if it is dnssec master if dnssec_masters and api.env.host not in dnssec_masters: print("DNSSEC key master(s):", u','.join(dnssec_masters)) raise ScriptError( "Only one DNSSEC key master is supported in current version.") if options.kasp_db_file: dnskeysyncd = services.service('ipa-dnskeysyncd') if not dnskeysyncd.is_installed(): raise RuntimeError("ipa-dnskeysyncd is not configured on this " "server, you cannot reuse OpenDNSSEC " "database (kasp.db file)") # check if replica can be the DNSSEC master cmd = [paths.IPA_DNSKEYSYNCD_REPLICA] environment = { "SOFTHSM2_CONF": paths.DNSSEC_SOFTHSM2_CONF, } # stop dnskeysyncd before test dnskeysyncd_running = dnskeysyncd.is_running() dnskeysyncd.stop() try: ipautil.run(cmd, env=environment, runas=constants.ODS_USER, suplementary_groups=[constants.NAMED_GROUP]) except CalledProcessError as e: root_logger.debug("%s", e) raise RuntimeError("This IPA server cannot be promoted to " "DNSSEC master role because some keys were " "not replicated from the original " "DNSSEC master server") finally: if dnskeysyncd_running: dnskeysyncd.start() elif dnssec_zones and not options.force: # some zones have --dnssec=true, make sure a user really want to # install new database raise RuntimeError( "DNSSEC signing is already enabled for following zone(s): %s\n" "Installation cannot continue without the OpenDNSSEC database " "file from the original DNSSEC master server.\n" "Please use option --kasp-db to specify location " "of the kasp.db file copied from the original " "DNSSEC master server.\n" "WARNING: Zones will become unavailable if you do not provide " "the original kasp.db file." % ", ".join([str(zone) for zone in dnssec_zones])) ip_addresses = get_server_ip_address(hostname, options.unattended, True, options.ip_addresses) util.network_ip_address_warning(ip_addresses) util.broadcast_ip_address_warning(ip_addresses) if not options.forward_policy: # user did not specify policy, derive it: default is 'first' but # if any of local IP addresses belongs to private ranges use 'only' options.forward_policy = 'first' for ip in ip_addresses: if dnsutil.inside_auto_empty_zone(dnsutil.DNSName(ip.reverse_dns)): options.forward_policy = 'only' root_logger.debug('IP address %s belongs to a private range, ' 'using forward policy only', ip) break if options.no_forwarders: options.forwarders = [] elif options.forwarders or options.auto_forwarders: if not options.forwarders: options.forwarders = [] if options.auto_forwarders: options.forwarders += resolver.get_default_resolver().nameservers elif standalone or not replica: options.forwarders = read_dns_forwarders() # test DNSSEC forwarders if options.forwarders: if (not bindinstance.check_forwarders(options.forwarders, root_logger) and not options.no_dnssec_validation): options.no_dnssec_validation = True print("WARNING: DNSSEC validation will be disabled") root_logger.debug("will use DNS forwarders: %s\n", options.forwarders) if not standalone: search_reverse_zones = False else: search_reverse_zones = True if not standalone and replica: reverse_zones_unattended_check = True else: reverse_zones_unattended_check = options.unattended reverse_zones = bindinstance.check_reverse_zones( ip_addresses, options.reverse_zones, options, reverse_zones_unattended_check, search_reverse_zones ) if reverse_zones: print("Using reverse zone(s) %s" % ', '.join(reverse_zones))
def install_check(standalone, api, replica, options, hostname): global ip_addresses global reverse_zones fstore = sysrestore.FileStore(paths.SYSRESTORE) if not ipautil.file_exists(paths.IPA_DNS_INSTALL): raise RuntimeError("Integrated DNS requires '%s' package" % constants.IPA_DNS_PACKAGE_NAME) # when installing first DNS instance we need to check zone overlap if replica or standalone: already_enabled = api.Command.dns_is_enabled()['result'] else: already_enabled = False if not already_enabled: domain = dnsutil.DNSName(util.normalize_zone(api.env.domain)) print("Checking DNS domain %s, please wait ..." % domain) try: dnsutil.check_zone_overlap(domain, raise_on_error=False) except ValueError as e: if options.force or options.allow_zone_overlap: root_logger.warning("%s Please make sure that the domain is " "properly delegated to this IPA server.", e) else: raise e for reverse_zone in options.reverse_zones: try: dnsutil.check_zone_overlap(reverse_zone) except ValueError as e: if options.force or options.allow_zone_overlap: root_logger.warning(six.text_type(e)) else: raise e if standalone: print("==============================================================================") print("This program will setup DNS for the FreeIPA Server.") print("") print("This includes:") print(" * Configure DNS (bind)") print(" * Configure SoftHSM (required by DNSSEC)") print(" * Configure ipa-dnskeysyncd (required by DNSSEC)") if options.dnssec_master: print(" * Configure ipa-ods-exporter (required by DNSSEC key master)") print(" * Configure OpenDNSSEC (required by DNSSEC key master)") print(" * Generate DNSSEC master key (required by DNSSEC key master)") elif options.disable_dnssec_master: print(" * Unconfigure ipa-ods-exporter") print(" * Unconfigure OpenDNSSEC") print("") print("No new zones will be signed without DNSSEC key master IPA server.") print("") print(("Please copy file from %s after uninstallation. This file is needed " "on new DNSSEC key " % paths.IPA_KASP_DB_BACKUP)) print("master server") print("") print("NOTE: DNSSEC zone signing is not enabled by default") print("") if options.dnssec_master: print("Plan carefully, replacing DNSSEC key master is not recommended") print("") print("") print("To accept the default shown in brackets, press the Enter key.") print("") if (options.dnssec_master and not options.unattended and not ipautil.user_input( "Do you want to setup this IPA server as DNSSEC key master?", False)): sys.exit("Aborted") elif (options.disable_dnssec_master and not options.unattended and not ipautil.user_input( "Do you want to disable current DNSSEC key master?", False)): sys.exit("Aborted") if options.disable_dnssec_master: _is_master() if options.disable_dnssec_master or options.dnssec_master: dnssec_zones = _find_dnssec_enabled_zones(api.Backend.ldap2) if options.disable_dnssec_master: if dnssec_zones and not options.force: raise RuntimeError( "Cannot disable DNSSEC key master, DNSSEC signing is still " "enabled for following zone(s):\n" "%s\n" "It is possible to move DNSSEC key master role to a different " "server by using --force option to skip this check.\n\n" "WARNING: You have to immediatelly copy kasp.db file to a new " "server and run command 'ipa-dns-install --dnssec-master " "--kasp-db'.\n" "Your DNS zones will become unavailable if you " "do not reinstall the DNSSEC key master role immediatelly." % ", ".join([str(zone) for zone in dnssec_zones])) elif options.dnssec_master: ods = opendnssecinstance.OpenDNSSECInstance(fstore) ods.realm = api.env.realm dnssec_masters = ods.get_masters() # we can reinstall current server if it is dnssec master if dnssec_masters and api.env.host not in dnssec_masters: print("DNSSEC key master(s):", u','.join(dnssec_masters)) raise ScriptError( "Only one DNSSEC key master is supported in current version.") if options.kasp_db_file: dnskeysyncd = services.service('ipa-dnskeysyncd', api) if not dnskeysyncd.is_installed(): raise RuntimeError("ipa-dnskeysyncd is not configured on this " "server, you cannot reuse OpenDNSSEC " "database (kasp.db file)") # check if replica can be the DNSSEC master cmd = [paths.IPA_DNSKEYSYNCD_REPLICA] environment = { "SOFTHSM2_CONF": paths.DNSSEC_SOFTHSM2_CONF, } # stop dnskeysyncd before test dnskeysyncd_running = dnskeysyncd.is_running() dnskeysyncd.stop() try: ipautil.run(cmd, env=environment, runas=constants.ODS_USER, suplementary_groups=[constants.NAMED_GROUP]) except CalledProcessError as e: root_logger.debug("%s", e) raise RuntimeError("This IPA server cannot be promoted to " "DNSSEC master role because some keys were " "not replicated from the original " "DNSSEC master server") finally: if dnskeysyncd_running: dnskeysyncd.start() elif dnssec_zones and not options.force: # some zones have --dnssec=true, make sure a user really want to # install new database raise RuntimeError( "DNSSEC signing is already enabled for following zone(s): %s\n" "Installation cannot continue without the OpenDNSSEC database " "file from the original DNSSEC master server.\n" "Please use option --kasp-db to specify location " "of the kasp.db file copied from the original " "DNSSEC master server.\n" "WARNING: Zones will become unavailable if you do not provide " "the original kasp.db file." % ", ".join([str(zone) for zone in dnssec_zones])) ip_addresses = get_server_ip_address(hostname, options.unattended, True, options.ip_addresses) util.network_ip_address_warning(ip_addresses) util.broadcast_ip_address_warning(ip_addresses) if not options.forward_policy: # user did not specify policy, derive it: default is 'first' but # if any of local IP addresses belongs to private ranges use 'only' options.forward_policy = 'first' for ip in ip_addresses: if dnsutil.inside_auto_empty_zone(dnsutil.DNSName(ip.reverse_dns)): options.forward_policy = 'only' root_logger.debug('IP address %s belongs to a private range, ' 'using forward policy only', ip) break if options.no_forwarders: options.forwarders = [] elif options.forwarders or options.auto_forwarders: if not options.forwarders: options.forwarders = [] if options.auto_forwarders: options.forwarders += resolver.get_default_resolver().nameservers elif standalone or not replica: options.forwarders = read_dns_forwarders() # test DNSSEC forwarders if options.forwarders: if (not bindinstance.check_forwarders(options.forwarders, root_logger) and not options.no_dnssec_validation): options.no_dnssec_validation = True print("WARNING: DNSSEC validation will be disabled") root_logger.debug("will use DNS forwarders: %s\n", options.forwarders) if not standalone: search_reverse_zones = False else: search_reverse_zones = True if not standalone and replica: reverse_zones_unattended_check = True else: reverse_zones_unattended_check = options.unattended reverse_zones = bindinstance.check_reverse_zones( ip_addresses, options.reverse_zones, options, reverse_zones_unattended_check, search_reverse_zones ) if reverse_zones: print("Using reverse zone(s) %s" % ', '.join(reverse_zones))
def install_check(installer): options = installer dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file http_pkcs12_file = installer._http_pkcs12_file pkinit_pkcs12_file = installer._pkinit_pkcs12_file dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info http_pkcs12_info = installer._http_pkcs12_info pkinit_pkcs12_info = installer._pkinit_pkcs12_info external_cert_file = installer._external_cert_file external_ca_file = installer._external_ca_file http_ca_cert = installer._ca_cert if tasks.is_fips_enabled(): raise RuntimeError( "Installing IPA server in FIPS mode is not supported") tasks.check_selinux_status() if options.master_password: msg = ("WARNING:\noption '-P/--master-password' is deprecated. " "KDC master password of sufficient strength is autogenerated " "during IPA server installation and should not be set " "manually.") print(textwrap.fill(msg, width=79, replace_whitespace=False)) installer._installation_cleanup = True print("\nThe log file for this installation can be found in " "/var/log/ipaserver-install.log") if (not options.external_ca and not options.external_cert_files and is_ipa_configured()): installer._installation_cleanup = False raise ScriptError( "IPA server is already configured on this system.\n" "If you want to reinstall the IPA server, please uninstall " "it first using 'ipa-server-install --uninstall'.") client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) if client_fstore.has_files(): installer._installation_cleanup = False raise ScriptError( "IPA client is already configured on this system.\n" "Please uninstall it before configuring the IPA server, " "using 'ipa-client-install --uninstall'") fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH) sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH) # This will override any settings passed in on the cmdline if ipautil.file_exists(paths.ROOT_IPA_CACHE): if options.dm_password is not None: dm_password = options.dm_password else: dm_password = read_password("Directory Manager", confirm=False) if dm_password is None: raise ScriptError("Directory Manager password required") try: cache_vars = read_cache(dm_password) options.__dict__.update(cache_vars) if cache_vars.get('external_ca', False): options.external_ca = False options.interactive = False except Exception as e: raise ScriptError("Cannot process the cache file: %s" % str(e)) # We only set up the CA if the PKCS#12 options are not given. if options.dirsrv_cert_files: setup_ca = False else: setup_ca = True options.setup_ca = setup_ca # first instance of KRA must be installed by ipa-kra-install options.setup_kra = False print("=======================================" "=======================================") print("This program will set up the FreeIPA Server.") print("") print("This includes:") if setup_ca: print(" * Configure a stand-alone CA (dogtag) for certificate " "management") if not options.no_ntp: print(" * Configure the Network Time Daemon (ntpd)") print(" * Create and configure an instance of Directory Server") print(" * Create and configure a Kerberos Key Distribution Center (KDC)") print(" * Configure Apache (httpd)") if options.setup_dns: print(" * Configure DNS (bind)") if not options.no_pkinit: print(" * Configure the KDC to enable PKINIT") if options.no_ntp: print("") print("Excluded by options:") print(" * Configure the Network Time Daemon (ntpd)") if installer.interactive: print("") print("To accept the default shown in brackets, press the Enter key.") print("") if not options.external_cert_files: # Make sure the 389-ds ports are available check_dirsrv(not installer.interactive) if not options.no_ntp: try: ipaclient.install.ntpconf.check_timedate_services() except ipaclient.install.ntpconf.NTPConflictingService as e: print(("WARNING: conflicting time&date synchronization service '%s'" " will be disabled" % e.conflicting_service)) print("in favor of ntpd") print("") except ipaclient.install.ntpconf.NTPConfigurationError: pass # Check to see if httpd is already configured to listen on 443 if httpinstance.httpd_443_configured(): raise ScriptError("Aborting installation") if not options.setup_dns and installer.interactive: if ipautil.user_input("Do you want to configure integrated DNS " "(BIND)?", False): options.setup_dns = True print("") # check bind packages are installed if options.setup_dns: # Don't require an external DNS to say who we are if we are # setting up a local DNS server. options.no_host_dns = True # check the hostname is correctly configured, it must be as the kldap # utilities just use the hostname as returned by getaddrinfo to set # up some of the standard entries if options.host_name: host_default = options.host_name else: host_default = get_fqdn() try: if not installer.interactive or options.host_name: verify_fqdn(host_default, options.no_host_dns) host_name = host_default else: host_name = read_host_name(host_default, options.no_host_dns) except BadHostError as e: raise ScriptError(e) host_name = host_name.lower() root_logger.debug("will use host_name: %s\n" % host_name) if not options.domain_name: domain_name = read_domain_name(host_name[host_name.find(".")+1:], not installer.interactive) root_logger.debug("read domain_name: %s\n" % domain_name) try: validate_domain_name(domain_name) except ValueError as e: raise ScriptError("Invalid domain name: %s" % unicode(e)) else: domain_name = options.domain_name domain_name = domain_name.lower() if not options.realm_name: realm_name = read_realm_name(domain_name, not installer.interactive) root_logger.debug("read realm_name: %s\n" % realm_name) else: realm_name = options.realm_name.upper() if not options.subject: options.subject = DN(('O', realm_name)) if options.http_cert_files: if options.http_pin is None: options.http_pin = installutils.read_password( "Enter Apache Server private key unlock", confirm=False, validate=False, retry=False) if options.http_pin is None: raise ScriptError( "Apache Server private key unlock password required") http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12( cert_files=options.http_cert_files, key_password=options.http_pin, key_nickname=options.http_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) http_pkcs12_info = (http_pkcs12_file.name, http_pin) if options.dirsrv_cert_files: if options.dirsrv_pin is None: options.dirsrv_pin = read_password( "Enter Directory Server private key unlock", confirm=False, validate=False, retry=False) if options.dirsrv_pin is None: raise ScriptError( "Directory Server private key unlock password required") dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12( cert_files=options.dirsrv_cert_files, key_password=options.dirsrv_pin, key_nickname=options.dirsrv_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin) if options.pkinit_cert_files: if not options.no_pkinit: raise ScriptError("Cannot create KDC PKINIT certificate and use " "provided external PKINIT certificate at the " "same time. Please choose one of them.") if options.pkinit_pin is None: options.pkinit_pin = read_password( "Enter Kerberos KDC private key unlock", confirm=False, validate=False, retry=False) if options.pkinit_pin is None: raise ScriptError( "Kerberos KDC private key unlock password required") pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12( cert_files=options.pkinit_cert_files, key_password=options.pkinit_pin, key_nickname=options.pkinit_cert_name, ca_cert_files=options.ca_cert_files, host_name=host_name) pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin) if (options.http_cert_files and options.dirsrv_cert_files and http_ca_cert != dirsrv_ca_cert): raise ScriptError( "Apache Server SSL certificate and Directory Server SSL " "certificate are not signed by the same CA certificate") if not options.dm_password: dm_password = read_dm_password() if dm_password is None: raise ScriptError("Directory Manager password required") else: dm_password = options.dm_password if not options.master_password: master_password = ipa_generate_password() else: master_password = options.master_password if not options.admin_password: admin_password = read_admin_password() if admin_password is None: raise ScriptError("IPA admin password required") else: admin_password = options.admin_password # Configuration for ipalib, we will bootstrap and finalize later, after # we are sure we have the configuration file ready. cfg = dict( context='installer', confdir=paths.ETC_IPA, in_server=True, # make sure host name specified by user is used instead of default host=host_name, ) if setup_ca: # we have an IPA-integrated CA cfg['ca_host'] = host_name # Create the management framework config file and finalize api target_fname = paths.IPA_DEFAULT_CONF fd = open(target_fname, "w") fd.write("[global]\n") fd.write("host=%s\n" % host_name) fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name)) fd.write("realm=%s\n" % realm_name) fd.write("domain=%s\n" % domain_name) fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name)) fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % installutils.realm_to_serverid(realm_name)) if setup_ca: fd.write("enable_ra=True\n") fd.write("ra_plugin=dogtag\n") fd.write("dogtag_version=10\n") else: fd.write("enable_ra=False\n") fd.write("ra_plugin=none\n") fd.write("mode=production\n") fd.close() # Must be readable for everyone os.chmod(target_fname, 0o644) api.bootstrap(**cfg) api.finalize() if setup_ca: ca.install_check(False, None, options) kra.install_check(api, None, options) if options.setup_dns: dns.install_check(False, api, False, options, host_name) ip_addresses = dns.ip_addresses else: ip_addresses = get_server_ip_address(host_name, not installer.interactive, False, options.ip_addresses) # check addresses here, dns module is doing own check network_ip_address_warning(ip_addresses) broadcast_ip_address_warning(ip_addresses) # installer needs to update hosts file when DNS subsystem will be # installed or custom addresses are used if options.ip_addresses or options.setup_dns: installer._update_hosts_file = True print() print("The IPA Master Server will be configured with:") print("Hostname: %s" % host_name) print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses)) print("Domain name: %s" % domain_name) print("Realm name: %s" % realm_name) print() if options.setup_dns: print("BIND DNS server will be configured to serve IPA domain with:") print("Forwarders: %s" % ( "No forwarders" if not options.forwarders else ", ".join([str(ip) for ip in options.forwarders]) )) print('Forward policy: %s' % options.forward_policy) print("Reverse zone(s): %s" % ( "No reverse zone" if options.no_reverse or not dns.reverse_zones else ", ".join(str(rz) for rz in dns.reverse_zones) )) print() # If domain name and realm does not match, IPA server will not be able # to estabilish trust with Active Directory. Print big fat warning. realm_not_matching_domain = (domain_name.upper() != realm_name) if realm_not_matching_domain: print("WARNING: Realm name does not match the domain name.\n" "You will not be able to estabilish trusts with Active " "Directory unless\nthe realm name of the IPA server matches " "its domain name.\n\n") if installer.interactive and not user_input( "Continue to configure the system with these values?", False): raise ScriptError("Installation aborted") options.realm_name = realm_name options.domain_name = domain_name options.dm_password = dm_password options.master_password = master_password options.admin_password = admin_password options._host_name_overridden = bool(options.host_name) options.host_name = host_name options.ip_addresses = ip_addresses installer._fstore = fstore installer._sstore = sstore installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file installer._http_pkcs12_file = http_pkcs12_file installer._pkinit_pkcs12_file = pkinit_pkcs12_file installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info installer._http_pkcs12_info = http_pkcs12_info installer._pkinit_pkcs12_info = pkinit_pkcs12_info installer._external_cert_file = external_cert_file installer._external_ca_file = external_ca_file installer._ca_cert = http_ca_cert