diff --git a/NEWS b/NEWS
index 8d7e2701ec6065f411d64626a509831d567c8f48..1d7fdb8cb373859cf639d90816077f377a56716d 100644
--- a/NEWS
+++ b/NEWS
@@ -85,6 +85,7 @@ Details
 - Reimplemented bash completion script to be more complete
 - Improved burnin
 - Added option to specify maximum timeout on instance shutdown
+- Added ``--no-ssh-init`` option to ``gnt-cluster init``
 
 
 Version 2.0.4
diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index 3eaf7efc71d839d6b7d8098d9e84fa0eb47e4240..0486dd1f5b6cb1ae28b2b5d7fe871cf2738df006 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -593,7 +593,7 @@ class NodeHttpServer(http.server.HttpServer):
     """Cleanup after leaving a cluster.
 
     """
-    return backend.LeaveCluster()
+    return backend.LeaveCluster(params[0])
 
   @staticmethod
   def perspective_node_volumes(params):
diff --git a/lib/backend.py b/lib/backend.py
index 8c906c9e602c34027fe3e7610b180657281e3cdd..e6eefec1c8a4ba73d03d1c7df6add4c39433316f 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -351,7 +351,7 @@ def AddNode(dsa, dsapub, rsa, rsapub, sshkey, sshpub):
   utils.RunCmd([constants.SSH_INITD_SCRIPT, "restart"])
 
 
-def LeaveCluster():
+def LeaveCluster(modify_ssh_setup):
   """Cleans up and remove the current node.
 
   This function cleans up and prepares the current node to be removed
@@ -361,19 +361,22 @@ def LeaveCluster():
   L{errors.QuitGanetiException} which is used as a special case to
   shutdown the node daemon.
 
+  @param modify_ssh_setup: boolean
+
   """
   _CleanDirectory(constants.DATA_DIR)
   JobQueuePurge()
 
-  try:
-    priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS)
+  if modify_ssh_setup:
+    try:
+      priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS)
 
-    utils.RemoveAuthorizedKey(auth_keys, utils.ReadFile(pub_key))
+      utils.RemoveAuthorizedKey(auth_keys, utils.ReadFile(pub_key))
 
-    utils.RemoveFile(priv_key)
-    utils.RemoveFile(pub_key)
-  except errors.OpExecError:
-    logging.exception("Error while processing ssh files")
+      utils.RemoveFile(priv_key)
+      utils.RemoveFile(pub_key)
+    except errors.OpExecError:
+      logging.exception("Error while processing ssh files")
 
   try:
     utils.RemoveFile(constants.HMAC_CLUSTER_KEY)
diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index 190cc261d213fbed442bbb24d4bca4a2e2c770c0..8e6d19b233277769c219ac3e573e930acb74ae08 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -138,7 +138,7 @@ def InitCluster(cluster_name, mac_prefix,
                 master_netdev, file_storage_dir, candidate_pool_size,
                 secondary_ip=None, vg_name=None, beparams=None,
                 nicparams=None, hvparams=None, enabled_hypervisors=None,
-                modify_etc_hosts=True):
+                modify_etc_hosts=True, modify_ssh_setup=True):
   """Initialise the cluster.
 
   @type candidate_pool_size: int
@@ -250,7 +250,8 @@ def InitCluster(cluster_name, mac_prefix,
   if modify_etc_hosts:
     utils.AddHostToEtcHosts(hostname.name)
 
-  _InitSSHSetup()
+  if modify_ssh_setup:
+    _InitSSHSetup()
 
   now = time.time()
 
@@ -273,6 +274,7 @@ def InitCluster(cluster_name, mac_prefix,
     hvparams=hvparams,
     candidate_pool_size=candidate_pool_size,
     modify_etc_hosts=modify_etc_hosts,
+    modify_ssh_setup=modify_ssh_setup,
     ctime=now,
     mtime=now,
     uuid=utils.NewUUID(),
@@ -335,11 +337,13 @@ def FinalizeClusterDestroy(master):
   begun in cmdlib.LUDestroyOpcode.
 
   """
+  cfg = config.ConfigWriter()
+  modify_ssh_setup = cfg.GetClusterInfo().modify_ssh_setup
   result = rpc.RpcRunner.call_node_stop_master(master, True)
   msg = result.fail_msg
   if msg:
     logging.warning("Could not disable the master role: %s" % msg)
-  result = rpc.RpcRunner.call_node_leave_cluster(master)
+  result = rpc.RpcRunner.call_node_leave_cluster(master, modify_ssh_setup)
   msg = result.fail_msg
   if msg:
     logging.warning("Could not shutdown the node daemon and cleanup"
diff --git a/lib/cli.py b/lib/cli.py
index eff591ef4236ddcb1d52e3c1f19d8c2d8745c52d..e79f6c633fe0e2d5f65af00db9bcf6aeb623436d 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -84,6 +84,7 @@ __all__ = [
   "NOIPCHECK_OPT",
   "NOLVM_STORAGE_OPT",
   "NOMODIFY_ETCHOSTS_OPT",
+  "NOMODIFY_SSH_SETUP_OPT",
   "NONICS_OPT",
   "NONLIVE_OPT",
   "NONPLUS1_OPT",
@@ -794,6 +795,10 @@ NOMODIFY_ETCHOSTS_OPT = cli_option("--no-etc-hosts", dest="modify_etc_hosts",
                                    help="Don't modify /etc/hosts",
                                    action="store_false", default=True)
 
+NOMODIFY_SSH_SETUP_OPT = cli_option("--no-ssh-init", dest="modify_ssh_setup",
+                                    help="Don't initialize SSH keys",
+                                    action="store_false", default=True)
+
 ERROR_CODES_OPT = cli_option("--error-codes", dest="error_codes",
                              help="Enable parseable error messages",
                              action="store_true", default=False)
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 3d0d8aaa094f18699787506bd5e8cf7a8617d94c..63378717f97aaedd66744e8d5eae05b6bd4c9675 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -867,6 +867,7 @@ class LUDestroyCluster(LogicalUnit):
 
     """
     master = self.cfg.GetMasterNode()
+    modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup
 
     # Run post hooks on master node before it's removed
     hm = self.proc.hmclass(self.rpc.call_hooks_runner, self)
@@ -877,9 +878,12 @@ class LUDestroyCluster(LogicalUnit):
 
     result = self.rpc.call_node_stop_master(master, False)
     result.Raise("Could not disable the master role")
-    priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS)
-    utils.CreateBackup(priv_key)
-    utils.CreateBackup(pub_key)
+
+    if modify_ssh_setup:
+      priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS)
+      utils.CreateBackup(priv_key)
+      utils.CreateBackup(pub_key)
+
     return master
 
 
@@ -2340,6 +2344,8 @@ class LURemoveNode(LogicalUnit):
     logging.info("Stopping the node daemon and removing configs from node %s",
                  node.name)
 
+    modify_ssh_setup = self.cfg.GetClusterInfo().modify_ssh_setup
+
     # Promote nodes to master candidate as needed
     _AdjustCandidatePool(self, exceptions=[node.name])
     self.context.RemoveNode(node.name)
@@ -2351,7 +2357,7 @@ class LURemoveNode(LogicalUnit):
     except:
       self.LogWarning("Errors occurred running hooks on %s" % node.name)
 
-    result = self.rpc.call_node_leave_cluster(node.name)
+    result = self.rpc.call_node_leave_cluster(node.name, modify_ssh_setup)
     msg = result.fail_msg
     if msg:
       self.LogWarning("Errors encountered on the remote node while leaving"
@@ -2900,20 +2906,21 @@ class LUAddNode(LogicalUnit):
                                (constants.PROTOCOL_VERSION, result.payload))
 
     # setup ssh on node
-    logging.info("Copy ssh key to node %s", node)
-    priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS)
-    keyarray = []
-    keyfiles = [constants.SSH_HOST_DSA_PRIV, constants.SSH_HOST_DSA_PUB,
-                constants.SSH_HOST_RSA_PRIV, constants.SSH_HOST_RSA_PUB,
-                priv_key, pub_key]
-
-    for i in keyfiles:
-      keyarray.append(utils.ReadFile(i))
-
-    result = self.rpc.call_node_add(node, keyarray[0], keyarray[1],
-                                    keyarray[2],
-                                    keyarray[3], keyarray[4], keyarray[5])
-    result.Raise("Cannot transfer ssh keys to the new node")
+    if self.cfg.GetClusterInfo().modify_ssh_setup:
+      logging.info("Copy ssh key to node %s", node)
+      priv_key, pub_key, _ = ssh.GetUserFiles(constants.GANETI_RUNAS)
+      keyarray = []
+      keyfiles = [constants.SSH_HOST_DSA_PRIV, constants.SSH_HOST_DSA_PUB,
+                  constants.SSH_HOST_RSA_PRIV, constants.SSH_HOST_RSA_PUB,
+                  priv_key, pub_key]
+
+      for i in keyfiles:
+        keyarray.append(utils.ReadFile(i))
+
+      result = self.rpc.call_node_add(node, keyarray[0], keyarray[1],
+                                      keyarray[2], keyarray[3], keyarray[4],
+                                      keyarray[5])
+      result.Raise("Cannot transfer ssh keys to the new node")
 
     # Add node to our /etc/hosts, and add key to known_hosts
     if self.cfg.GetClusterInfo().modify_etc_hosts:
diff --git a/lib/objects.py b/lib/objects.py
index 510518ab1f2ae40c4d0193bad0932cd809483fdd..969901c51a83ccca2618c9dc202527e378596ff0 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -825,6 +825,7 @@ class Cluster(TaggableObject):
     "nicparams",
     "candidate_pool_size",
     "modify_etc_hosts",
+    "modify_ssh_setup",
     ] + _TIMESTAMPS + _UUID
 
   def UpgradeConfig(self):
@@ -850,6 +851,9 @@ class Cluster(TaggableObject):
     if self.modify_etc_hosts is None:
       self.modify_etc_hosts = True
 
+    if self.modify_ssh_setup is None:
+      self.modify_ssh_setup = True
+
     # default_bridge is no longer used it 2.1. The slot is left there to
     # support auto-upgrading, but will be removed in 2.2
     if self.default_bridge is not None:
diff --git a/lib/rpc.py b/lib/rpc.py
index 8701945ab9b958bd875aa1b5d6a6e76683b0c3a1..780f601fc8eee04ac4c78cab3e8d83c29032cade 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -1044,7 +1044,7 @@ class RpcRunner(object):
     return self._SingleNodeCall(node, "export_remove", [export])
 
   @classmethod
-  def call_node_leave_cluster(cls, node):
+  def call_node_leave_cluster(cls, node, modify_ssh_setup):
     """Requests a node to clean the cluster information it has.
 
     This will remove the configuration information from the ganeti data
@@ -1053,7 +1053,8 @@ class RpcRunner(object):
     This is a single-node call.
 
     """
-    return cls._StaticSingleNodeCall(node, "node_leave_cluster", [])
+    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
+                                     [modify_ssh_setup])
 
   def call_node_volumes(self, node_list):
     """Gets all volumes on node(s).
diff --git a/man/gnt-cluster.sgml b/man/gnt-cluster.sgml
index 53131470475ea349b29197ff736e81c6a8ed6578..afd1cb20831a330e3ffc5f52f360731b6302054d 100644
--- a/man/gnt-cluster.sgml
+++ b/man/gnt-cluster.sgml
@@ -221,6 +221,10 @@
         <sbr>
         <arg>--no-lvm-storage</arg>
         <sbr>
+        <arg>--no-etc-hosts</arg>
+        <sbr>
+        <arg>--no-ssh-init</arg>
+        <sbr>
         <arg>--file-storage-dir <replaceable>dir</replaceable></arg>
         <sbr>
         <arg>--enabled-hypervisors <replaceable>hypervisors</replaceable></arg>
@@ -296,13 +300,23 @@
       </para>
 
       <para>
-        The <option>--no-lvm-storage</option> allows you to initialize the
-        cluster without lvm support. This means that only instances using
+        The <option>--no-lvm-storage</option> option allows you to initialize
+        the cluster without lvm support. This means that only instances using
         files as storage backend will be possible to create. Once the cluster
         is initialized you can change this setup with the
         <command>modify</command> command.
       </para>
 
+      <para>
+        The <option>--no-etc-hosts</option> option allows you to initialize the
+        cluster without modifying the <filename>/etc/hosts</filename> file.
+      </para>
+
+      <para>
+        The <option>--no-ssh-init</option> option allows you to initialize the
+        cluster without creating or distributing SSH key pairs.
+      </para>
+
       <para>
         The <option>--file-storage-dir</option> option allows you
         set the directory to use for storing the instance disk
diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster
index a57b9a0ea81de39238d3d7c6764024070dddfd3e..555e72ed745f5c0a0151d6c4ed1af6c9c2420194 100755
--- a/scripts/gnt-cluster
+++ b/scripts/gnt-cluster
@@ -99,6 +99,7 @@ def InitCluster(opts, args):
                         nicparams=nicparams,
                         candidate_pool_size=opts.candidate_pool_size,
                         modify_etc_hosts=opts.modify_etc_hosts,
+                        modify_ssh_setup=opts.modify_ssh_setup,
                         )
   op = opcodes.OpPostInitCluster()
   SubmitOpCode(op)
@@ -600,7 +601,8 @@ commands = {
     InitCluster, [ArgHost(min=1, max=1)],
     [BACKEND_OPT, CP_SIZE_OPT, ENABLED_HV_OPT, GLOBAL_FILEDIR_OPT,
      HVLIST_OPT, MAC_PREFIX_OPT, MASTER_NETDEV_OPT, NIC_PARAMS_OPT,
-     NOLVM_STORAGE_OPT, NOMODIFY_ETCHOSTS_OPT, SECONDARY_IP_OPT, VG_NAME_OPT],
+     NOLVM_STORAGE_OPT, NOMODIFY_ETCHOSTS_OPT, NOMODIFY_SSH_SETUP_OPT,
+     SECONDARY_IP_OPT, VG_NAME_OPT],
     "[opts...] <cluster_name>", "Initialises a new cluster configuration"),
   'destroy': (
     DestroyCluster, ARGS_NONE, [YES_DOIT_OPT],