[CRIU] [PATCH 3/3] p.haul: enable ssh tunneling with ssh* cmdline opts

Ruslan Kuprieiev kupruser at gmail.com
Sat Oct 18 14:12:50 PDT 2014


Currently, all p.haul traffic goes without any encryption, which is
not safe at all, cosidering that attacker can easily peek memory pages
of migrating process. Lets solve that by using ssh tunnel which allows
us to easily encrypt and compress traffic.
Compressing is useful only when connection is very slow, but will only
slow down things on fast networks.
Using ssh tunnel also allows us to solve keys\certificates management
problem in a very common way that is familiar to any system administrator.

Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
---
 p.haul        | 17 ++++++++++++++++-
 ssh_tunnel.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 ssh_tunnel.py

diff --git a/p.haul b/p.haul
index 129bc4f..ec42381 100755
--- a/p.haul
+++ b/p.haul
@@ -5,6 +5,7 @@ import p_haul_iters as ph_iters
 import images
 import criu_api
 import xem_rpc
+import ssh_tunnel
 
 # Usage idea
 # p.haul <type> <id> <destination>
@@ -39,13 +40,27 @@ parser.add_argument("--dst-rpid", help = "Write pidfile on restore", default = N
 parser.add_argument("--img-path", help = "Dirctory where to put images", default = images.def_path)
 parser.add_argument("--pid-root", help = "Path to tree's FS root")
 parser.add_argument("--force", help = "Don't do any sanity (CPU compat) checks", default = False, action = 'store_true')
+parser.add_argument("--ssh", help = "Use ssh tunnel to encrypt traffic", default = False, action = "store_true")
+parser.add_argument("--ssh-compression", help = "Use compression in the tunnel", default = False, action = "store_true")
+parser.add_argument("--ssh-username", help = "Remote username", type = str)
+parser.add_argument("--ssh-port", help = "Port to connect to ssh on the remote host", default = ssh_tunnel.def_ssh_port, type = int)
+parser.add_argument("--ssh-local-port", help = "Local port to forward", type = int, default = ssh_tunnel.def_loc_port)
 
 args = vars(parser.parse_args())
 
+args["to"] = parse_dest(args.pop("to"))
+
+ssh = ssh_tunnel.Tunnel()
+args = ssh.filter_opts(args)
+ssh.start()
+
 ph_type = (args.pop("type"), args.pop("id"))
-dst = parse_dest(args.pop("to"))
+dst = args.pop("to")
+
 
 # Start the migration
 worker = ph_iters.phaul_iter_worker(ph_type, dst)
 worker.set_options(args)
 worker.start_migration()
+
+ssh.stop()
diff --git a/ssh_tunnel.py b/ssh_tunnel.py
new file mode 100644
index 0000000..7a5e764
--- /dev/null
+++ b/ssh_tunnel.py
@@ -0,0 +1,54 @@
+import os
+
+def_ssh_port = 22
+def_loc_port = 54321
+
+class Tunnel:
+	def __init__(self):
+		self._cmd = None
+
+	def filter_opts(self, opts):
+		# Pop() all "ssh*" opts. If ssh tunnel is requested,
+		# set "to" option to (localhost, local_port).
+
+		use_ssh = opts.pop("ssh")
+		ssh_user = opts.pop("ssh_username")
+		ssh_address = opts["to"][0]
+		remote_port = opts["to"][1]
+		local_port = opts.pop("ssh_local_port")
+		ssh_port = opts.pop("ssh_port")
+		use_compression = opts.pop("ssh_compression")
+
+		if not use_ssh:
+			self._cmd = None
+			return opts
+
+		self._opts = {}
+		self._opts["ssh_remote"] = ssh_user+"@"+ssh_address if ssh_user else ssh_address
+		self._opts["ssh_port"] = ssh_port
+		self._opts["local_port"] = local_port
+		self._opts["remote_port"] = remote_port
+		self._opts["compress"] = "C" if use_compression else ""
+
+		self._cmd = "ssh -fN{compress} -L {local_port}:localhost:{remote_port} -p {ssh_port} {ssh_remote}".format(**self._opts)
+
+		opts["to"] = ("127.0.0.1", local_port)
+
+		return opts
+
+	def start(self):
+		if not self._cmd:
+			return
+
+		os.system(self._cmd)
+		while os.system("pkill -0 -f \"" + self._cmd + "\""):
+			print("waiting")
+
+		print("SSH tunnel(cmd: %s) started" %self._cmd)
+
+	def stop(self):
+		if not self._cmd:
+			return
+
+		os.system("pkill -9 -f \"" + self._cmd + "\"")
+		print ("SSH tunnel stopped")
-- 
1.9.3



More information about the CRIU mailing list