Show More
@@ -224,14 +224,59 b' run code. When you start ipython qtconsole, there will be an output line,' | |||||
224 | like:: |
|
224 | like:: | |
225 |
|
225 | |||
226 | [IPKernelApp] To connect another client to this kernel, use: |
|
226 | [IPKernelApp] To connect another client to this kernel, use: | |
227 | [IPKernelApp] --existing --shell=60690 --iopub=44045 --stdin=38323 --hb=41797 |
|
227 | [IPKernelApp] --existing kernel-12345.json | |
228 |
|
228 | |||
229 | Other frontends can connect to your kernel, and share in the execution. This is |
|
229 | Other frontends can connect to your kernel, and share in the execution. This is | |
230 | great for collaboration. The ``--existing`` flag means connect to a kernel |
|
230 | great for collaboration. The ``--existing`` flag means connect to a kernel | |
231 | that already exists. Starting other |
|
231 | that already exists. Starting other consoles | |
232 |
|
|
232 | with that flag will not try to start their own kernel, but rather connect to | |
233 | yours. Ultimately, you will not have to specify each port individually, but for |
|
233 | yours. :file:`kernel-12345.json` is a small JSON file with the ip, port, and | |
234 | now this copy-paste method is best. |
|
234 | authentication information necessary to connect to your kernel. By default, this file | |
|
235 | will be in your default profile's security directory. If it is somewhere else, | |||
|
236 | the output line will print the full path of the connection file, rather than | |||
|
237 | just its filename. | |||
|
238 | ||||
|
239 | If you need to find the connection info to send, and don't know where your connection file | |||
|
240 | lives, there are a couple of ways to get it. If you are already running an IPython console | |||
|
241 | connected to the kernel, you can use the ``%connect_info`` magic to display the information | |||
|
242 | necessary to connect another frontend to the kernel. | |||
|
243 | ||||
|
244 | .. sourcecode:: ipython | |||
|
245 | ||||
|
246 | In [2]: %connect_info | |||
|
247 | { | |||
|
248 | "stdin_port":50255, | |||
|
249 | "ip":"127.0.0.1", | |||
|
250 | "hb_port":50256, | |||
|
251 | "key":"70be6f0f-1564-4218-8cda-31be40a4d6aa", | |||
|
252 | "shell_port":50253, | |||
|
253 | "iopub_port":50254 | |||
|
254 | } | |||
|
255 | ||||
|
256 | Paste the above JSON into a file, and connect with: | |||
|
257 | $> ipython <app> --existing <file> | |||
|
258 | or, if you are local, you can connect with just: | |||
|
259 | $> ipython <app> --existing kernel-12345.json | |||
|
260 | or even just: | |||
|
261 | $> ipython <app> --existing | |||
|
262 | if this is the most recent IPython session you have started. | |||
|
263 | ||||
|
264 | Otherwise, you can find a connection file by name (and optionally profile) with | |||
|
265 | :func:`IPython.lib.kernel.find_connection_file`: | |||
|
266 | ||||
|
267 | .. sourcecode:: bash | |||
|
268 | ||||
|
269 | $> python -c "from IPython.lib.kernel import find_connection_file;\ | |||
|
270 | print find_connection_file('kernel-12345.json')" | |||
|
271 | /home/you/.ipython/profile_default/security/kernel-12345.json | |||
|
272 | ||||
|
273 | And if you are using a particular IPython profile: | |||
|
274 | ||||
|
275 | .. sourcecode:: bash | |||
|
276 | ||||
|
277 | $> python -c "from IPython.lib.kernel import find_connection_file;\ | |||
|
278 | print find_connection_file('kernel-12345.json', profile='foo')" | |||
|
279 | /home/you/.ipython/profile_foo/security/kernel-12345.json | |||
235 |
|
280 | |||
236 | You can even launch a standalone kernel, and connect and disconnect Qt Consoles |
|
281 | You can even launch a standalone kernel, and connect and disconnect Qt Consoles | |
237 | from various machines. This lets you keep the same running IPython session |
|
282 | from various machines. This lets you keep the same running IPython session | |
@@ -240,7 +285,7 b' caf\xc3\xa9s, etc.::' | |||||
240 |
|
285 | |||
241 | $> ipython kernel |
|
286 | $> ipython kernel | |
242 | [IPKernelApp] To connect another client to this kernel, use: |
|
287 | [IPKernelApp] To connect another client to this kernel, use: | |
243 | [IPKernelApp] --existing --shell=60690 --iopub=44045 --stdin=38323 --hb=41797 |
|
288 | [IPKernelApp] --existing kernel-12345.json | |
244 |
|
289 | |||
245 | This is actually exactly the same as the subprocess launched by the qtconsole, so |
|
290 | This is actually exactly the same as the subprocess launched by the qtconsole, so | |
246 | all the information about connecting to a standalone kernel is identical to that |
|
291 | all the information about connecting to a standalone kernel is identical to that | |
@@ -253,10 +298,10 b' Security' | |||||
253 |
|
298 | |||
254 | .. warning:: |
|
299 | .. warning:: | |
255 |
|
300 | |||
256 |
Since the ZMQ code currently has no |
|
301 | Since the ZMQ code currently has no encryption, listening on an | |
257 | external-facing IP is dangerous. You are giving any computer that can see |
|
302 | external-facing IP is dangerous. You are giving any computer that can see | |
258 | you on the network the ability to issue arbitrary shell commands as you on |
|
303 | you on the network the ability to connect to your kernel, and view your traffic. | |
259 |
|
|
304 | Read the rest of this section before listening on external ports | |
260 | or running an IPython kernel on a shared machine. |
|
305 | or running an IPython kernel on a shared machine. | |
261 |
|
306 | |||
262 | By default (for security reasons), the kernel only listens on localhost, so you |
|
307 | By default (for security reasons), the kernel only listens on localhost, so you | |
@@ -266,41 +311,41 b' argument::' | |||||
266 |
|
311 | |||
267 | $> ipython qtconsole --ip=192.168.1.123 |
|
312 | $> ipython qtconsole --ip=192.168.1.123 | |
268 |
|
313 | |||
269 |
If you specify the ip as 0.0.0.0, that |
|
314 | If you specify the ip as 0.0.0.0 or '*', that means all interfaces, so any | |
270 | computer that can see yours on the network can connect to the kernel. |
|
315 | computer that can see yours on the network can connect to the kernel. | |
271 |
|
316 | |||
272 | Messages are not encrypted, so users with access to the ports your kernel is using will be |
|
317 | Messages are not encrypted, so users with access to the ports your kernel is using will be | |
273 |
able to see any output of the kernel. They will |
|
318 | able to see any output of the kernel. They will **NOT** be able to issue shell commands as | |
274 | you, unless you enable HMAC digests, which are **DISABLED** by default. |
|
319 | you due to message signatures, which are enabled by default as of IPython 0.12. | |
|
320 | ||||
|
321 | .. warning:: | |||
275 |
|
322 | |||
276 | The one security feature IPython does provide is protection from unauthorized |
|
323 | If you disable message signatures, then any user with access to the ports your | |
277 | execution. IPython's messaging system can sign messages with HMAC digests using |
|
324 | kernel is listening on can issue arbitrary code as you. **DO NOT** disable message | |
278 | a shared-key. The key is never sent over the network, it is only used to generate |
|
325 | signatures unless you have a lot of trust in your environment. | |
279 | a unique hash for each message, based on its content. When IPython receives a |
|
326 | ||
280 | message, it will check that the digest matches. You can use any file that only you |
|
327 | The one security feature IPython does provide is protection from unauthorized execution. | |
281 | have access to to generate this key. One logical choice would be to use your own |
|
328 | IPython's messaging system will sign messages with HMAC digests using a shared-key. The key | |
282 | SSH private key. Or you can generate a new random private key with:: |
|
329 | is never sent over the network, it is only used to generate a unique hash for each message, | |
|
330 | based on its content. When IPython receives a message, it will check that the digest | |||
|
331 | matches, and discard the message. You can use any file that only you have access to to | |||
|
332 | generate this key, but the default is just to generate a new UUID. You can generate a random | |||
|
333 | private key with:: | |||
283 |
|
334 | |||
284 | # generate 1024b of random data, and store in a file only you can read: |
|
335 | # generate 1024b of random data, and store in a file only you can read: | |
285 | # (assumes IPYTHON_DIR is defined, otherwise use your IPython directory) |
|
336 | # (assumes IPYTHON_DIR is defined, otherwise use your IPython directory) | |
286 | $> python -c "import os; print os.urandom(128).encode('base64')" > $IPYTHON_DIR/sessionkey |
|
337 | $> python -c "import os; print os.urandom(128).encode('base64')" > $IPYTHON_DIR/sessionkey | |
287 | $> chmod 600 $IPYTHON_DIR/sessionkey |
|
338 | $> chmod 600 $IPYTHON_DIR/sessionkey | |
288 |
|
339 | |||
289 | To enable HMAC digests, simply specify the ``Session.keyfile`` configurable |
|
340 | The *contents* of this file will be stored in the JSON connection file, so that file | |
|
341 | contains everything you need to connect to and use a kernel. | |||
|
342 | ||||
|
343 | To use this generated key, simply specify the ``Session.keyfile`` configurable | |||
290 | in :file:`ipython_config.py` or at the command-line, as in:: |
|
344 | in :file:`ipython_config.py` or at the command-line, as in:: | |
291 |
|
345 | |||
292 |
# instruct IPython to sign messages with that key |
|
346 | # instruct IPython to sign messages with that key, instead of a new UUID | |
293 | $> ipython qtconsole --Session.keyfile=$IPYTHON_DIR/sessionkey |
|
347 | $> ipython qtconsole --Session.keyfile=$IPYTHON_DIR/sessionkey | |
294 |
|
348 | |||
295 | You must use the same key you used to start the kernel with all frontends, or |
|
|||
296 | they will be treated as an unauthorized peer (all messages will be ignored). |
|
|||
297 |
|
||||
298 | .. note:: |
|
|||
299 |
|
||||
300 | IPython will move to using files to store connection information, as is |
|
|||
301 | done in :mod:`IPython.parallel`, at which point HMAC signatures will be |
|
|||
302 | enabled *by default*. |
|
|||
303 |
|
||||
304 | .. _ssh_tunnels: |
|
349 | .. _ssh_tunnels: | |
305 |
|
350 | |||
306 | SSH Tunnels |
|
351 | SSH Tunnels | |
@@ -314,13 +359,14 b' machine, to which you have SSH access.' | |||||
314 |
|
359 | |||
315 | In simple cases, IPython's tools can forward ports over ssh by simply adding the |
|
360 | In simple cases, IPython's tools can forward ports over ssh by simply adding the | |
316 | ``--ssh=remote`` argument to the usual ``--existing...`` set of flags for connecting |
|
361 | ``--ssh=remote`` argument to the usual ``--existing...`` set of flags for connecting | |
317 | to a running kernel. |
|
362 | to a running kernel, after copying the JSON connection file (or its contents) to | |
|
363 | the second computer. | |||
318 |
|
364 | |||
319 | .. warning:: |
|
365 | .. warning:: | |
320 |
|
366 | |||
321 | Using SSH tunnels does *not* increase localhost security. In fact, when |
|
367 | Using SSH tunnels does *not* increase localhost security. In fact, when | |
322 | tunneling from one machine to another *both* machines have open |
|
368 | tunneling from one machine to another *both* machines have open | |
323 | ports on localhost available for connections. |
|
369 | ports on localhost available for connections to the kernel. | |
324 |
|
370 | |||
325 | There are two primary models for using SSH tunnels with IPython. The first |
|
371 | There are two primary models for using SSH tunnels with IPython. The first | |
326 | is to have the Kernel listen only on localhost, and connect to it from |
|
372 | is to have the Kernel listen only on localhost, and connect to it from | |
@@ -331,17 +377,20 b' on loopback::' | |||||
331 |
|
377 | |||
332 | user@worker $> ipython kernel |
|
378 | user@worker $> ipython kernel | |
333 | [IPKernelApp] To connect another client to this kernel, use: |
|
379 | [IPKernelApp] To connect another client to this kernel, use: | |
334 | [IPKernelApp] --existing --shell=59480 --iopub=62199 --stdin=64898 --hb=56511 |
|
380 | [IPKernelApp] --existing kernel-12345.json | |
335 |
|
381 | |||
336 | In this case, the IP that you would connect |
|
382 | In this case, the IP that you would connect | |
337 | to would still be 127.0.0.1, but you want to specify the additional ``--ssh`` argument |
|
383 | to would still be 127.0.0.1, but you want to specify the additional ``--ssh`` argument | |
338 | with the hostname of the kernel (in this example, it's 'worker'):: |
|
384 | with the hostname of the kernel (in this example, it's 'worker'):: | |
339 |
|
385 | |||
340 |
user@client $> ipython qtconsole --ssh=worker --existing |
|
386 | user@client $> ipython qtconsole --ssh=worker --existing /path/to/kernel-12345.json | |
|
387 | ||||
|
388 | Which will write a new connection file with the forwarded ports, so you can reuse them:: | |||
|
389 | ||||
|
390 | [IPythonQtConsoleApp] To connect another client via this tunnel, use: | |||
|
391 | [IPythonQtConsoleApp] --existing kernel-12345-ssh.json | |||
341 |
|
392 | |||
342 | Note again that this opens ports on the *client* machine that point to your kernel. |
|
393 | Note again that this opens ports on the *client* machine that point to your kernel. | |
343 | Be sure to use a Session key, as described above, if localhost on *either* the |
|
|||
344 | client or kernel machines is untrusted. |
|
|||
345 |
|
394 | |||
346 | .. note:: |
|
395 | .. note:: | |
347 |
|
396 | |||
@@ -357,13 +406,18 b' on external interfaces, so that its ports are visible to `login`::' | |||||
357 |
|
406 | |||
358 | user@worker $> ipython kernel --ip=0.0.0.0 |
|
407 | user@worker $> ipython kernel --ip=0.0.0.0 | |
359 | [IPKernelApp] To connect another client to this kernel, use: |
|
408 | [IPKernelApp] To connect another client to this kernel, use: | |
360 | [IPKernelApp] --existing --shell=59480 --iopub=62199 --stdin=64898 --hb=56511 |
|
409 | [IPKernelApp] --existing kernel-12345.json | |
361 |
|
410 | |||
362 | Which we can connect to from the client with:: |
|
411 | Which we can connect to from the client with:: | |
363 |
|
412 | |||
364 |
user@client $> ipython qtconsole --ssh=login --ip=192.168.1.123 --existing |
|
413 | user@client $> ipython qtconsole --ssh=login --ip=192.168.1.123 --existing /path/to/kernel-12345.json | |
|
414 | ||||
|
415 | .. note:: | |||
|
416 | ||||
|
417 | The IP here is the address of worker as seen from *login*, and need only be specified if | |||
|
418 | the kernel used the ambiguous 0.0.0.0 (all interfaces) address. If it had used | |||
|
419 | 192.168.1.123 to start with, it would not be needed. | |||
365 |
|
420 | |||
366 | Note that now the IP is the address of worker as seen from login. |
|
|||
367 |
|
421 | |||
368 | Manual SSH tunnels |
|
422 | Manual SSH tunnels | |
369 | ------------------ |
|
423 | ------------------ |
General Comments 0
You need to be logged in to leave comments.
Login now