GNS3 / gns3-web-ui

WebUI implementation for GNS3
GNU General Public License v3.0
149 stars 52 forks source link

Access web consoles without credentials #959

Open grossmj opened 4 years ago

grossmj commented 4 years ago

We should implement a way for users to only access web consoles without credentials (this should be an option in the preferences). See https://github.com/GNS3/gns3-server/issues/1805 for details.

piotrpekala7 commented 4 years ago

I read your comments under https://github.com/GNS3/gns3-server/issues/1805, I have no clue

piotrpekala7 commented 4 years ago

I'll try to find any information

piotrpekala7 commented 4 years ago

blocked by https://github.com/GNS3/gns3-web-ui/issues/958, firstly we should resolve problems with authentication

piotrpekala7 commented 4 years ago

the same as https://github.com/GNS3/gns3-web-ui/issues/958

candlerb commented 4 years ago

I have been trying to access the web console page via a proxy which adds the Authorization header, but it's turned up a couple of issues.

Proxy config (Apache2 mod_rewrite):

        RequestHeader set Authorization "Basic XXXX" "expr=%{REQUEST_URI} =~ m#^(/static/web-ui/|/v2/projects/[0-9a-f-]+/nodes/[0-9a-f-]+)#"
        RewriteRule "^(/static/web-ui/.*)$" "http://127.0.0.1:3080$1" [L,P]
        RewriteRule "^(/v2/projects/[0-9a-f-]+/nodes/[0-9a-f-]+)$" "http://127.0.0.1:3080$1" [L,P]
        RewriteRule "^(/v2/.*/console/ws)$" "ws://127.0.0.1:3080$1" [L,P]

This fetches the blank console page, and I can see it's proxying various /static/web-ui/... assets, but then pops up the following error in a box:

Uncaught (in promise): TypeError: Cannot read property 'host' of undefined TypeError: Cannot read property 'host' of undefined
 at t.getOptionsForServer (https://gns3.example.net/static/web-ui/main.fc6e4d196640e6d4d699.js:1:1568968)
 at t.get (https://gns3.example.net/static/web-ui/main.fc6e4d196640e6d4d699.js:1:1567063)
 at t.getNodeById (https://gns3.example.net/static/web-ui/main.fc6e4d196640e6d4d699.js:1:1799920)
 at https://gns3.example.net/static/web-ui/main.fc6e4d196640e6d4d699.js:1:3081330
 at e.invoke (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:7309)
 at Object.onInvoke (https://gns3.example.net/static/web-ui/main.fc6e4d196640e6d4d699.js:1:855039)
 at e.invoke (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:7249)
 at t.run (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:2409)
 at https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:14332
 at e.invokeTask (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:7993)
 at Object.onInvokeTask (https://gns3.example.net/static/web-ui/main.fc6e4d196640e6d4d699.js:1:854922)
 at e.invokeTask (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:7914)
 at t.runTask (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:3072)
 at _ (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:10309)
 at t.invokeTask [as invoke] (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:9154)
 at f (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:22252)
 at IDBRequest.h (https://gns3.example.net/static/web-ui/polyfills.e3de9c33e285997df00a.js:1:22485)

I notice "IDBRequest" in there, which makes me think that the Javascript rendering the console is dependent on some client-side state stored from a previous request.

Also: when not using the proxy, but using a web browser talking directly to the web-ui and successfully opening a console, I notice that it is making an API GET to /v2/projects/<X>/nodes/<Y>. I'm not sure why it's doing this - perhaps just to map the node UUID to its name, or to check that it is running? I did allow for it in the proxy config, but tcpdump shows it's not getting this far anyway. It is another reason why accessing the web console without credentials may be problematic, since this API call will be rejected.

candlerb commented 4 years ago

FYI, I am now using a small bit of HTML to make a console connection:

<!doctype html>
<html>
<head>
    <link rel="stylesheet" href="https://unpkg.com/xterm@4.8.1/css/xterm.css" />
    <script src="https://unpkg.com/xterm@4.8.1/lib/xterm.js"></script>
    <script src="https://unpkg.com/xterm-addon-fit@0.4.0/lib/xterm-addon-fit.js"></script>
    <script src="https://unpkg.com/xterm-addon-attach@0.6.0/lib/xterm-addon-attach.js"></script>
</head>
<body>
<div id="terminal" style="height: 100vh;"></div>
<script>
var term = new Terminal();
var fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);

term.open(document.getElementById('terminal'));
fitAddon.fit();
term.focus();

var socket = new WebSocket('ws://x.x.x.x:3080/v2/projects/xxxxx/nodes/xxxxx/console/ws');
var attachAddon = new AttachAddon.AttachAddon(socket);

term.write('\x1B[1;3;31mHit Enter to wake...\x1B[0m\r\n');
term.loadAddon(attachAddon);
</script>
</body>
</html>

You still need to identify the project UUID and node UUID of the device you want to connect to, to build the websocket path. I'm using a CGI to generate this page with that set dynamically.