summaryrefslogtreecommitdiffstats
path: root/install/tools
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2011-05-22 19:17:07 +0200
committerMartin Kosek <mkosek@redhat.com>2011-06-08 09:29:52 +0200
commit241ee334defda108e22855331d5d9a14f261ce16 (patch)
tree7bfaaeeb2673f473423d6aa418142468fa4b6dd9 /install/tools
parent8077b7ab938f436582b3985c1b6fd0ad90e8bb3d (diff)
downloadfreeipa-241ee334defda108e22855331d5d9a14f261ce16.tar.gz
freeipa-241ee334defda108e22855331d5d9a14f261ce16.tar.xz
freeipa-241ee334defda108e22855331d5d9a14f261ce16.zip
Connection check program for replica installation
When connection between a master machine and future replica is not sane, the replica installation may fail unexpectedly with inconvenient error messages. One common problem is misconfigured firewall. This patch adds a program ipa-replica-conncheck which tests the connection using the following procedure: 1) Execute the on-replica check testing the connection to master 2) Open required ports on local machine 3) Ask user to run the on-master part of the check OR run it automatically: a) kinit to master as default admin user with given password b) run the on-master part using ssh 4) When master part is executed, it checks connection back to the replica and prints the check result This program is run by ipa-replica-install as mandatory part. It can, however, be skipped using --skip-conncheck option. ipa-replica-install now requires password for admin user to run the command on remote master. https://fedorahosted.org/freeipa/ticket/1107
Diffstat (limited to 'install/tools')
-rw-r--r--install/tools/Makefile.am1
-rwxr-xr-xinstall/tools/ipa-replica-conncheck372
-rwxr-xr-xinstall/tools/ipa-replica-install40
-rw-r--r--install/tools/man/Makefile.am1
-rw-r--r--install/tools/man/ipa-replica-conncheck.187
-rw-r--r--install/tools/man/ipa-replica-install.16
6 files changed, 507 insertions, 0 deletions
diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am
index 055a32fca..9004bb248 100644
--- a/install/tools/Makefile.am
+++ b/install/tools/Makefile.am
@@ -7,6 +7,7 @@ SUBDIRS = \
sbin_SCRIPTS = \
ipa-dns-install \
ipa-server-install \
+ ipa-replica-conncheck \
ipa-replica-install \
ipa-replica-prepare \
ipa-replica-manage \
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
new file mode 100755
index 000000000..06cec2cfd
--- /dev/null
+++ b/install/tools/ipa-replica-conncheck
@@ -0,0 +1,372 @@
+#! /usr/bin/python -E
+# Authors: Martin Kosek <mkosek@redhat.com>
+#
+# Copyright (C) 2011 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+from ipapython.config import IPAOptionParser
+from ipapython import version
+from ipapython import ipautil
+from ipapython.ipautil import CalledProcessError
+import ipaclient.ipachangeconf
+from optparse import OptionGroup
+import logging
+import sys
+import os
+import signal
+import tempfile
+import getpass
+import socket
+import time
+import threading
+import errno
+
+CONNECT_TIMEOUT = 5
+RESPONDERS = [ ]
+QUIET = False
+CCACHE_FILE = "/etc/ipa/.conncheck_ccache"
+KRB5_CONFIG = None
+
+class CheckedPort(object):
+ def __init__(self, port, stream, description):
+ self.port = port
+ self.stream = stream
+ self.description = description
+
+BASE_PORTS = [
+ CheckedPort(389, True, "Directory Service: unsecure port"),
+ CheckedPort(636, True, "Directory Service: secure port"),
+ CheckedPort(88, False, "Kerberos"),
+ ]
+
+CA_PORTS = [
+ CheckedPort(7389, True, "PKI-CA: Directory Service"),
+ CheckedPort(9444, True, "PKI-CA: EE Secure port"),
+ CheckedPort(9445, True, "PKI-CA: Admin Secure port"),
+ CheckedPort(9446, True, "PKI-CA: EE Secure Client Auth port"),
+ CheckedPort(9180, True, "PKI-CA: Unsecure port"),
+ ]
+
+def print_info(msg):
+ if not QUIET:
+ print msg
+
+def parse_options():
+ parser = IPAOptionParser(version=version.VERSION)
+
+ replica_group = OptionGroup(parser, "on-replica options")
+ replica_group.add_option("-m", "--master", dest="master",
+ help="Master address with running IPA for output connection check")
+ replica_group.add_option("-a", "--auto-master-check", dest="auto_master_check",
+ action="store_true",
+ default=False,
+ help="Automatically execute connection check on master")
+ replica_group.add_option("-r", "--realm", dest="realm",
+ help="Realm name")
+ replica_group.add_option("-k", "--kdc", dest="kdc",
+ help="Master KDC. Defaults to master address")
+ replica_group.add_option("-p", "--principal", dest="principal",
+ default="admin", help="Principal to use to log in to remote master")
+ replica_group.add_option("-w", "--password", dest="password", sensitive=True,
+ help="Password for the principal"),
+ parser.add_option_group(replica_group)
+
+
+ master_group = OptionGroup(parser, "on-master options")
+ master_group.add_option("-R", "--replica", dest="replica",
+ help="Address of remote replica machine to check against")
+ parser.add_option_group(master_group)
+
+ common_group = OptionGroup(parser, "common options")
+ common_group.add_option("-c", "--check-ca", dest="check_ca",
+ action="store_true",
+ default=False,
+ help="Check also ports for Certificate Authority")
+
+ common_group.add_option("", "--hostname", dest="hostname",
+ help="The hostname of this server (FQDN). "
+ "By default a nodename from uname(2) is used.")
+ parser.add_option_group(common_group)
+
+ parser.add_option("-d", "--debug", dest="debug",
+ action="store_true",
+ default=False, help="Print debugging information")
+ parser.add_option("-q", "--quiet", dest="quiet",
+ action="store_true",
+ default=False, help="Output only errors")
+
+ options, args = parser.parse_args()
+ safe_options = parser.get_safe_opts(options)
+
+ if options.master and options.replica:
+ parser.error("on-master and on-replica options are mutually exclusive!")
+
+ if options.master:
+ if options.auto_master_check and not options.realm:
+ parser.error("Realm is parameter is required to connect to remote master!")
+ if not os.getegid() == 0:
+ parser.error("You can only run on-replica part as root.")
+
+ if options.master and not options.kdc:
+ options.kdc = options.master
+
+ if not options.master and not options.replica:
+ parser.error("No action: you should select either --replica or --master option.")
+
+ if not options.hostname:
+ options.hostname = socket.getfqdn()
+
+ if options.quiet:
+ global QUIET
+ QUIET = True
+
+ return safe_options, options
+
+def logging_setup(options):
+ if os.getegid() == 0:
+ log_file = "/var/log/ipareplica-conncheck.log"
+ old_umask = os.umask(077)
+ logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(levelname)s %(message)s',
+ filename=log_file,
+ filemode='w')
+ os.umask(old_umask)
+
+ console = logging.StreamHandler()
+ # If the debug option is set, also log debug messages to the console
+ if options.debug:
+ console.setLevel(logging.DEBUG)
+ else:
+ # Otherwise, log critical and error messages
+ console.setLevel(logging.ERROR)
+ formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
+ console.setFormatter(formatter)
+ logging.getLogger('').addHandler(console)
+
+def clean_responders(responders):
+ if not responders:
+ return
+
+ for responder in responders:
+ responder.stop()
+
+ for responder in responders:
+ responder.join()
+ responders.remove(responder)
+
+def sigterm_handler(signum, frame):
+ print_info("\nCleaning up...")
+
+ global RESPONDERS
+ clean_responders(RESPONDERS)
+
+ sys.exit(1)
+
+def configure_krb5_conf(realm, kdc, filename):
+
+ krbconf = ipaclient.ipachangeconf.IPAChangeConf("IPA Installer")
+ krbconf.setOptionAssignment(" = ")
+ krbconf.setSectionNameDelimiters(("[","]"))
+ krbconf.setSubSectionDelimiters(("{","}"))
+ krbconf.setIndent((""," "," "))
+
+ opts = [{'name':'comment', 'type':'comment', 'value':'File created by ipa-replica-conncheck'},
+ {'name':'empty', 'type':'empty'}]
+
+ #[libdefaults]
+ libdefaults = [{'name':'default_realm', 'type':'option', 'value':realm}]
+ libdefaults.append({'name':'dns_lookup_realm', 'type':'option', 'value':'false'})
+ libdefaults.append({'name':'dns_lookup_kdc', 'type':'option', 'value':'false'})
+ libdefaults.append({'name':'rdns', 'type':'option', 'value':'false'})
+ libdefaults.append({'name':'ticket_lifetime', 'type':'option', 'value':'24h'})
+ libdefaults.append({'name':'forwardable', 'type':'option', 'value':'yes'})
+
+ opts.append({'name':'libdefaults', 'type':'section', 'value': libdefaults})
+ opts.append({'name':'empty', 'type':'empty'})
+
+ #the following are necessary only if DNS discovery does not work
+ #[realms]
+ realms_info =[{'name':'kdc', 'type':'option', 'value':kdc+':88'},
+ {'name':'admin_server', 'type':'option', 'value':kdc+':749'}]
+ realms = [{'name':realm, 'type':'subsection', 'value':realms_info}]
+
+ opts.append({'name':'realms', 'type':'section', 'value':realms})
+ opts.append({'name':'empty', 'type':'empty'})
+
+ #[appdefaults]
+ pamopts = [{'name':'debug', 'type':'option', 'value':'false'},
+ {'name':'ticket_lifetime', 'type':'option', 'value':'36000'},
+ {'name':'renew_lifetime', 'type':'option', 'value':'36000'},
+ {'name':'forwardable', 'type':'option', 'value':'true'},
+ {'name':'krb4_convert', 'type':'option', 'value':'false'}]
+ appopts = [{'name':'pam', 'type':'subsection', 'value':pamopts}]
+ opts.append({'name':'appdefaults', 'type':'section', 'value':appopts})
+
+ logging.debug("Writing temporary Kerberos configuration to %s:\n%s"
+ % (filename, krbconf.dump(opts)))
+
+ krbconf.newConf(filename, opts)
+
+class PortResponder(threading.Thread):
+
+ def __init__(self, port, socket_stream = True, socket_timeout=1):
+ super(PortResponder, self).__init__()
+ self.port = port
+ self.socket_stream = socket_stream
+ self.socket_timeout = socket_timeout
+ self._stop_request = False
+
+ def run(self):
+ while not self._stop_request:
+ try:
+ ipautil.bind_port_responder(self.port, self.socket_stream,
+ self.socket_timeout, responder_data="FreeIPA")
+ except socket.timeout:
+ pass
+ except socket.error, e:
+ if e.errno == errno.EADDRINUSE:
+ time.sleep(1)
+ else:
+ raise
+
+ def stop(self):
+ self._stop_request = True
+
+def port_check(host, port_list):
+ failed_ports = []
+ for port in port_list:
+ if ipautil.host_port_open(host, port.port, port.stream, CONNECT_TIMEOUT):
+ result = "OK"
+ else:
+ failed_ports.append(port)
+ result = "FAILED"
+ print_info(" %s (%d): %s" % (port.description, port.port, result))
+
+ if failed_ports:
+ msg_ports = ", ".join([str(port.port) for port in failed_ports])
+ raise RuntimeError("Port check failed! Inaccessible port(s): %s" % msg_ports)
+
+def main():
+ safe_options, options = parse_options()
+
+ logging_setup(options)
+ logging.debug('%s was invoked with options: %s' % (sys.argv[0], safe_options))
+ logging.debug("missing options might be asked for interactively later\n")
+
+ signal.signal(signal.SIGTERM, sigterm_handler)
+ signal.signal(signal.SIGINT, sigterm_handler)
+
+ required_ports = BASE_PORTS
+ if options.check_ca:
+ required_ports.extend(CA_PORTS)
+
+ if options.replica:
+ print_info("Check connection from master to remote replica '%s':" % options.replica)
+ port_check(options.replica, required_ports)
+ print_info("\nConnection from master to replica is OK.")
+
+ # kinit to foreign master
+ if options.master:
+ # check ports on master first
+ print_info("Check connection from replica to remote master '%s':" % options.master)
+ port_check( options.master, required_ports)
+ print_info("\nConnection from replica to master is OK.")
+
+ # create listeners
+ global RESPONDERS
+ print_info("Start listening on required ports for remote master check")
+ for port in required_ports:
+ logging.debug("Start listening on port %d (%s)" % (port.port, port.description))
+ responder = PortResponder(port.port, port.stream)
+ responder.start()
+ RESPONDERS.append(responder)
+
+ if options.auto_master_check:
+ (krb_fd, krb_name) = tempfile.mkstemp()
+ os.close(krb_fd)
+ configure_krb5_conf(options.realm, options.kdc, krb_name)
+ global KRB5_CONFIG
+ KRB5_CONFIG = krb_name
+
+ print_info("Get credentials to log in to remote master")
+ if options.principal.find('@') == -1:
+ principal = '%s@%s' % (options.principal, options.realm)
+ user = options.principal
+ else:
+ principal = options.principal
+ user = options.principal.partition('@')[0]
+
+ if options.password:
+ password=options.password
+ else:
+ password = getpass.getpass("Password for %s: " % principal)
+
+ stderr=''
+ (stdout, stderr, returncode) = ipautil.run(['/usr/bin/kinit', principal],
+ env={'KRB5_CONFIG':KRB5_CONFIG, 'KRB5CCNAME':CCACHE_FILE},
+ stdin=password, raiseonerr=False)
+ if returncode != 0:
+ raise RuntimeError("Cannot acquire Kerberos ticket: %s" % stderr)
+
+ remote_check_opts = ['--replica %s' % options.hostname]
+ if options.check_ca:
+ remote_check_opts.append('--check-ca')
+
+ print_info("Execute check on remote master")
+
+ stderr = ''
+ remote_addr = "%s@%s" % (user, options.master)
+ (stdout, stderr, returncode) = ipautil.run(['/usr/bin/ssh', remote_addr,
+ "/usr/sbin/ipa-replica-conncheck " + " ".join(remote_check_opts)],
+ env={'KRB5_CONFIG':KRB5_CONFIG, 'KRB5CCNAME' : CCACHE_FILE},
+ raiseonerr=False)
+
+ print_info(stdout)
+
+ if returncode != 0:
+ raise RuntimeError("Remote master check failed with following error message(s):\n%s" % stderr)
+ else:
+ # wait until user test is ready
+ print_info("Listeners are started. Use CTRL+C to terminate the listening part after the test.")
+ print_info("")
+ print_info("Please run the following command on remote master:")
+
+ remote_check_opts = ['--replica %s' % options.hostname]
+ if options.check_ca:
+ remote_check_opts.append('--check-ca')
+ print_info("/usr/sbin/ipa-replica-conncheck " + " ".join(remote_check_opts))
+ time.sleep(3600)
+ print_info("Connection check timeout: terminating listening program")
+
+if __name__ == "__main__":
+ try:
+ sys.exit(main())
+ except SystemExit, e:
+ sys.exit(e)
+ except KeyboardInterrupt:
+ sys.exit(1)
+ except RuntimeError, e:
+ sys.exit(e)
+ finally:
+ clean_responders(RESPONDERS)
+ for file_name in (CCACHE_FILE, KRB5_CONFIG):
+ if file_name:
+ try:
+ os.remove(file_name)
+ except OSError:
+ pass
+
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 2848366dd..f91ac51a6 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -38,6 +38,7 @@ from ipapython.config import IPAOptionParser
from ipapython import sysrestore
CACERT="/etc/ipa/ca.crt"
+REPLICA_INFO_TOP_DIR=None
class ReplicaConfig:
def __init__(self):
@@ -58,6 +59,8 @@ def parse_options():
default=False, help="gather extra debugging information")
parser.add_option("-p", "--password", dest="password", sensitive=True,
help="Directory Manager (existing master) password")
+ parser.add_option("-w", "--admin-password", dest="admin_password", sensitive=True,
+ help="Admin user Kerberos password used for connection check")
parser.add_option("--setup-dns", dest="setup_dns", action="store_true",
default=False, help="configure bind with our zone")
parser.add_option("--forwarder", dest="forwarders", action="append",
@@ -71,6 +74,8 @@ def parse_options():
help="Do not use DNS for hostname lookup during installation")
parser.add_option("--no-pkinit", dest="setup_pkinit", action="store_false",
default=True, help="disables pkinit setup steps")
+ parser.add_option("--skip-conncheck", dest="skip_conncheck", action="store_true",
+ default=False, help="skip connection check to remote master")
parser.add_option("-U", "--unattended", dest="unattended", action="store_true",
default=False, help="unattended installation never prompts the user")
@@ -388,6 +393,8 @@ def main():
try:
top_dir, dir = expand_info(filename, dirman_password)
+ global REPLICA_INFO_TOP_DIR
+ REPLICA_INFO_TOP_DIR = top_dir
except Exception, e:
print "ERROR: Failed to decrypt or open the replica file."
print "Verify you entered the correct Directory Manager password."
@@ -408,6 +415,32 @@ def main():
sys.exit(0)
config.dir = dir
+
+ # check connection
+ if not options.skip_conncheck:
+ print "Run connection check to master"
+ args = ["/usr/sbin/ipa-replica-conncheck", "--master", config.master_host_name,
+ "--auto-master-check", "--realm", config.realm_name,
+ "--principal", "admin",
+ "--hostname", config.host_name]
+
+ if options.admin_password:
+ args.extend(["--password", options.admin_password])
+
+ cafile = config.dir + "/cacert.p12"
+ if ipautil.file_exists(cafile): # with CA
+ args.append('--check-ca')
+ logging.debug("Running ipa-replica-conncheck with following arguments: %s" %
+ " ".join(args))
+ (stdin, stderr, returncode) = ipautil.run(args,raiseonerr=False, capture_output=False)
+
+ if returncode != 0:
+ sys.exit("Connection check failed!" +
+ "\nPlease fix your network settings according to error messages above." +
+ "\nIf the check results are not valid it can be skipped with --skip-conncheck parameter.")
+ else:
+ print "Connection check OK"
+
# Create the management framework config file
# Note: We must do this before bootstraping and finalizing ipalib.api
fd = open("/etc/ipa/default.conf", "w")
@@ -555,6 +588,13 @@ except Exception, e:
logging.debug(message)
except KeyboardInterrupt:
print "Installation cancelled."
+finally:
+ # always try to remove decrypted replica file
+ try:
+ if REPLICA_INFO_TOP_DIR:
+ shutil.rmtree(REPLICA_INFO_TOP_DIR)
+ except OSError:
+ pass
print ""
print "Your system may be partly configured."
diff --git a/install/tools/man/Makefile.am b/install/tools/man/Makefile.am
index 3fac378c9..be2524e86 100644
--- a/install/tools/man/Makefile.am
+++ b/install/tools/man/Makefile.am
@@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = 1.7
NULL=
man1_MANS = \
+ ipa-replica-conncheck.1 \
ipa-replica-install.1 \
ipa-replica-manage.1 \
ipa-replica-prepare.1 \
diff --git a/install/tools/man/ipa-replica-conncheck.1 b/install/tools/man/ipa-replica-conncheck.1
new file mode 100644
index 000000000..21fa24ccc
--- /dev/null
+++ b/install/tools/man/ipa-replica-conncheck.1
@@ -0,0 +1,87 @@
+.\" A man page for ipa-replica-conncheck
+.\" Copyright (C) 2011 Red Hat, Inc.
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation, either version 3 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+.\" General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.\"
+.\" Author: Martin Kosek <mkosek@redhat.com>
+.\"
+.TH "ipa-replica-conncheck" "1" "Jun 2 2011" "freeipa" ""
+.SH "NAME"
+ipa\-replica\-conncheck \- Check a replica\-master network connection before installation
+.SH "SYNOPSIS"
+ipa\-replica\-conncheck [\fIOPTION\fR]...
+.SH "DESCRIPTION"
+When an IPA replica is being installed a network connection between a replica machine and a replicated IPA master machine has to be prepared for master\-replica communication. In case of a flawed connection the installation may fail with inconvenient error messages. A common connection problem is a misconfigured firewall with closed required port on a replica or master machine.
+
+The connection is checked by running a set of tests from both master and replica machines. The program is incorporated to ipa\-replica\-install(1) but can be also run separately.
+
+.SH "OPTIONS"
+.SS "REPLICA MACHINE OPTIONS"
+This set of options is used when the connection check is run on a prepared IPA replica machine.
+.TP
+\fB\-m\fR \fIMASTER\fR, \fB\-\-master\fR=\fIMASTER\fR
+Remote master machine address
+.TP
+\fB\-a\fR, \fB\-\-auto\-master\-check\fR
+Automatically log in to master machine and execute the master machine part of the connection check. The following options for replica part are only evaluated when this option is set
+.TP
+\fB\-r\fR \fIREALM\fR, \fB\-\-realm\fR=\fIREALM\fR
+The Kerberos realm name for the IPA server
+.TP
+\fB\-k\fR \fIKDC\fR, \fB\-\-kdc\fR=\fIKDC\fR
+KDC server address. Defaults t \fIMASTER\fR
+.TP
+\fB\-p\fR \fIPRINCIPAL\fR, \fB\-\-principal\fR=\fIPRINCIPAL\fR
+Authorized Kerberos principal to use to log in to master machine. Defaults to \fIadmin\fR
+.TP
+\fB\-w\fR \fIPASSWORD\fR, \fB\-\-password\fR=\fIPASSWORD\fR
+Password for given principal. The password will be prompted interactively when this option is missing
+
+.SS "MASTER MACHINE OPTIONS"
+This set of options is used when the connection check is run on a master machine against a running ipa\-replica\-conncheck(1) on a replica machine.
+.TP
+\fB\-R\fR \fIREPLICA\fR, \fB\-\-replica\fR=\fIREPLICA\fR
+Remote replica machine address
+
+.SS "COMMON OPTIONS"
+.TP
+\fB\-c\fR, \fB\-\-check\-ca\fR
+Include in a check also a set of dogtag connection requirements. When a replica is self\-sign this option is not needed.
+.TP
+\fB\-h\fR \fIHOSTNAME\fR, \fB\-\-hostname\fR=\fIHOSTNAME\fR
+The hostname of this server (FQDN). By default a nodename from uname(2) is used
+.TP
+\fB\-d\fR, \fB\-\-debug\fR
+Print debugging information
+.TP
+\fB\-q\fR, \fB\-\-quiet\fR
+Output only errors
+
+.SH "EXAMPLES"
+.TP
+\fBipa-replica-conncheck -m master.example.com\fR
+Run a replica machine connection check against a remote master \fImaster.example.com\fR. If the connection to the remote master machine is successful the program will switch to listening mode and prompt for running the master machine part. The second part check the connection from master to replica.
+.TP
+\fBipa-replica-conncheck -R replica.example.com\fR
+Run a master machine connection check part. This is either run automatically by replica part of the connection check program (when \fI-a\fR option is set) or manually by the user. A running ipa-replica-conncheck(1) in a listening mode must be already running on a replica machine.
+.TP
+\fBipa-replica-conncheck -m master.example.com -a -r EXAMPLE.COM -w password\fR
+Run a replica\-master connection check. In case of a success switch to listening mode, automatically log to \fImaster.example.com\fR in a realm \fIEXAMPLE.COM\fR with a password \fIpassword\fR and run the second part of the connection check.
+
+.SH "EXIT STATUS"
+0 if the connection check was successful
+
+1 if an error occurred
+.SH "SEE ALSO"
+.BR ipa-replica-install (1)
diff --git a/install/tools/man/ipa-replica-install.1 b/install/tools/man/ipa-replica-install.1
index 3ee304224..888923546 100644
--- a/install/tools/man/ipa-replica-install.1
+++ b/install/tools/man/ipa-replica-install.1
@@ -36,6 +36,9 @@ Enable debug logging when more verbose output is needed
\fB\-p\fR, \fB\-\-password\fR=\fIDM_PASSWORD\fR
Directory Manager (existing master) password
.TP
+\fB\-w\fR \fIADMIN_PASSWORD\fR, \fB\-\-admin\-password\fR=\fIADMIN_PASSWORD\fR
+Admin user Kerberos password used for connection check
+.TP
\fB\-\-setup\-dns\fR
Generate a DNS zone if it does not exist already and configure the DNS server.
This option requires that you either specify at least one DNS forwarder through
@@ -58,6 +61,9 @@ Do not use DNS for hostname lookup during installation
\fB\-\-no\-pkinit\fR
Disables pkinit setup steps
.TP
+\fB\-\-skip\-conncheck\fR
+Skip connection check to remote master
+.TP
\fB\-U\fR, \fB\-\-unattended\fR
An unattended installation that will never prompt for user input
.SH "EXIT STATUS"