Pluto over local network?

Is there anything preventing Pluto.jl from being used on a local network? When starting Pluto, using Pluto;Pluto.run(), it gives a local address, http://localhost:1234/?secret=Nagu3EAW. If I substitute localhost with the computer’s network IP address it fails to find it.

If it’s not Pluto’s problem, which I suspect is the case, can anyone point me in the correct direction? I have asked a network admin but he didn’t know why it wasn’t working either.

Windows 10 Enterprise (10.0.19041 Build 19041)
Julia Version 1.6.2
Commit 1b93d53fc4 (2021-07-14 15:36 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-11.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 7

julia> Pkg.status()
      Status `C:\Users\Max\.julia\environments\v1.6\Project.toml`
  [336ed68f] CSV v0.8.5
  [a93c6f00] DataFrames v1.2.2
  [c3e4b0f8] Pluto v0.16.1
  [d330b81b] PyPlot v2.9.0
  [295af30f] Revise v3.1.19
  [0aa819cd] SQLite v1.1.4
  [69024149] StringEncodings v0.3.5
  [44cfe95a] Pkg
  [de0858da] Printf

Doesn’t Pluto.run(;host="0.0.0.0") work for you?

3 Likes

It works?! What is special about 0.0.0.0?

Locally when it tries to load http://0.0.0.0:1234/... it gives what looks like an Apache error message. When I try from another computer on the network it works! The same works on the computer running Julia, replacing 0.0.0.0 with the actual IP address.

It is mentioned in the docs, but not explained very well what it actually does. In my understanding it just tells Pluto to accept connections from any address (0.0.0.0 is denoting a wildcard here) instead of just from localhost (127.0.0.1).

help?> Pluto.run
  Pluto.run()


  Start Pluto!

  Keyword arguments
  ===================

  You can configure some of Pluto's more technical behaviour using keyword
  arguments, but this is mostly meant to support testing and strange setups
  like Docker. If you want to do something exciting with Pluto, you can
  probably write a creative notebook to do it!

  Pluto.run(; kwargs...)


  For the full list, see the Pluto.Configuration module. Some common
  parameters:

    •  launch_browser: Optional. Whether to launch the system default
       browser. Disable this on SSH and such.

    •  host: Optional. The default host is "127.0.0.1". For wild setups
       like Docker and heroku, you might need to change this to
       "0.0.0.0".

    •  port: Optional. The default port is 1234.

  Technobabble
  ==============

  This will start the static HTTP server and a WebSocket server. The server
  runs synchronously (i.e. blocking call) on http://[host]:[port]/. Pluto
  notebooks can be started from the main menu in the web browser.

  ────────────────────────────────────────────────────────────────────────────

  run(session::ServerSession)


  Specifiy the Pluto.ServerSession to run the web server on, which includes
  the configuration. Passing a session as argument allows you to start the web
  server with some notebooks already running. See SessionActions to learn more
  about manipulating a ServerSession.
2 Likes

This is correct. To explain further:

Computer can have more than one IP address (one for each network interface available). By default, modern computers have a so-called loopback device, which has the IP address 127.0.0.1. In contrast, 0.0.0.0 means “all IP addresses” (depending on context, all on the internet, all on this device…) What’s meant in this case is “all IP addresses of all interfaces on this computer”. So when you bind (i.e. Telling a server to listen for incoming connections on the given IP/interface) to 0.0.0.0, it listens for any incoming connections to this computer (i.e. Any packet coming through the network, including the loopback). In contrast, listening only on 127.0.0.1 only allows connections that come from this same computer, since it only listens on the loopback device.

The reason Pluto doesn’t do this by default is because it’s a security problem - listening on 0.0.0.0 allows ANYONE with access to your network to connect to your Pluto instance on your machine, allowing them to execute arbitrary code as part of that Pluto/julia instance (barring any explicit firewall rules governing access). You usually don’t want that. If you want to access your Pluto instance remotely, it’s safer to only bind Pluto locally (i.e. to the default 127.0.0.1) and use SSH port forwarding to securely access the Pluto instance. That way, you have to authenticate to your computer when trying to use the “remote” Pluto instance when setting up the SSH connection, shielding your computer from unwanted or malicious access.

4 Likes

That was a great explanation but I wanted to be a little pedantic here because people often misunderstand this and it becomes a lot more relevant for IPv6… There is no reason that you can’t have many IP addresses on any given interface. With ipv4 this is usually not done for scarcity reasons… However you can absolutely put more than one. But with IPv6 it’s common to have 5-10 IP addresses per interface, and it’s practically required to have more than one (link local, ULA, and SLAAC for example, then there are privacy addresses, and DHCP as well)

1 Like

Right - I omitted that because it’s not relevant to the explanation of “what is that weird 127.0.0.1 or 0.0.0.0 here? Why does one work and not the other?” :slight_smile: You’re of course correct in that this is a vast oversimplification, but in practice it’s good enough™ here.

1 Like