New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session cookie gets lost when running an OctoPrint instance on a subpath of another #2137

Closed
foosel opened this Issue Oct 2, 2017 · 6 comments

Comments

2 participants
@foosel
Owner

foosel commented Oct 2, 2017

Problem

Running an OctoPrint instance on the subpath of another causes that instance to receive the cookies for the path of the first instance and its own path. Tornado then causes only one set to arrive since it doesn't support multi valued cookie headers, and that can be the wrong one, effectively making the session get lost. This causes issues during first time setup when attempting to make changes that require a login session (past initial ACL setup), like the mandatory connectivity check configuration which then cannot be completed. This effectively locks the user in a setup wizard they can't complete.

Note: This was discovered while looking into #2095 (comment), which according to the reporter however should rather be caused by issues with port numbers (see #2095 (comment)). OctoPrint has already been encoding into the cookie name for quite a while. It is still unclear what exactly caused #2095 (comment).

Solution

Just like with the port number, also encode the script root/prefix into the cookie name. Replace / with | since / is not allowed in cookie names. Leave / without suffix. A session cookie for an OctoPrint instance running on port 80 and with path prefix /octoprint thus becomes session_P80_R|octoprint, an instance on a subpath /octoprint/2 becomes session_P80_R|octoprint|2, / leads to session_P80 just like before.

Implemented in 4fe6e05 and 7fc0f48

@mgrl

This comment has been minimized.

Show comment
Hide comment
@mgrl

mgrl Oct 3, 2017

coming from #2095, you asked for the full haproxy-config. sorry for the delay.
here it is:

global
        maxconn 4096
        user haproxy
        group haproxy
        log 127.0.0.1 local1 debug

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor
        maxconn 2000
        timeout connect 5s
        timeout client  15min
        timeout server  15min

frontend public
        bind *:80
        bind 0.0.0.0:443 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend octoprint
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        reqadd X-Scheme:\ https if { ssl_fc }
        option forwardfor
        server octoprint1 127.0.0.1:5000

backend webcam
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam1  127.0.0.1:8080

frontend public2
        bind *:81
        bind 0.0.0.0:444 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam2 if { path_beg /webcam/ }
        default_backend octoprint2
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend octoprint2
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        reqadd X-Scheme:\ https if { ssl_fc }
        option forwardfor
        server octoprint2 127.0.0.1:5001

backend webcam2
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam2  127.0.0.1:8081


frontend public3
        bind *:82
        bind 0.0.0.0:445 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam3 if { path_beg /webcam/ }
        default_backend octoprint3
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend octoprint3
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        reqadd X-Scheme:\ https if { ssl_fc }
        option forwardfor
        server octoprint3 127.0.0.1:5002

backend webcam3
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam3  127.0.0.1:8082

and a screenshot of the cookies in firefox:
cookies

now I just set up a fourth instance and made a screenshot in firefox. it seems, as if a wrong cookie is presented to the server? see here:
devtools

there are several 403-errors listed. each time I click "Onlineprüfung aktivieren" one error is issued. maybe that helps? I will leave the instance as is if you need further details/tests made.

mgrl commented Oct 3, 2017

coming from #2095, you asked for the full haproxy-config. sorry for the delay.
here it is:

global
        maxconn 4096
        user haproxy
        group haproxy
        log 127.0.0.1 local1 debug

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option redispatch
        option http-server-close
        option forwardfor
        maxconn 2000
        timeout connect 5s
        timeout client  15min
        timeout server  15min

frontend public
        bind *:80
        bind 0.0.0.0:443 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend octoprint
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        reqadd X-Scheme:\ https if { ssl_fc }
        option forwardfor
        server octoprint1 127.0.0.1:5000

backend webcam
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam1  127.0.0.1:8080

frontend public2
        bind *:81
        bind 0.0.0.0:444 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam2 if { path_beg /webcam/ }
        default_backend octoprint2
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend octoprint2
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        reqadd X-Scheme:\ https if { ssl_fc }
        option forwardfor
        server octoprint2 127.0.0.1:5001

backend webcam2
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam2  127.0.0.1:8081


frontend public3
        bind *:82
        bind 0.0.0.0:445 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        use_backend webcam3 if { path_beg /webcam/ }
        default_backend octoprint3
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

backend octoprint3
        reqrep ^([^\ :]*)\ /(.*) \1\ /\2
        reqadd X-Scheme:\ https if { ssl_fc }
        option forwardfor
        server octoprint3 127.0.0.1:5002

backend webcam3
        reqrep ^([^\ :]*)\ /webcam/(.*)     \1\ /\2
        server webcam3  127.0.0.1:8082

and a screenshot of the cookies in firefox:
cookies

now I just set up a fourth instance and made a screenshot in firefox. it seems, as if a wrong cookie is presented to the server? see here:
devtools

there are several 403-errors listed. each time I click "Onlineprüfung aktivieren" one error is issued. maybe that helps? I will leave the instance as is if you need further details/tests made.

@foosel

This comment has been minimized.

Show comment
Hide comment
@foosel

foosel Oct 3, 2017

Owner

Hm, that haproxy config looks just fine.

The Cookies it sends on request appear to be truncated in that screenshot view though (at least when I compare what's listed there fore me here and what the Cookies tab right next to that says it sent). What does it say in the Cookies tab?

I just tried again with a current Firefox, one existing instance on port 80, another fresh one on port 81. For me it sends all the cookies and no session data gets lost:

image

image

edit Did you enable or disable ACL?

Owner

foosel commented Oct 3, 2017

Hm, that haproxy config looks just fine.

The Cookies it sends on request appear to be truncated in that screenshot view though (at least when I compare what's listed there fore me here and what the Cookies tab right next to that says it sent). What does it say in the Cookies tab?

I just tried again with a current Firefox, one existing instance on port 80, another fresh one on port 81. For me it sends all the cookies and no session data gets lost:

image

image

edit Did you enable or disable ACL?

@mgrl

This comment has been minimized.

Show comment
Hide comment
@mgrl

mgrl Oct 3, 2017

okay, every cookie is set in the request, it seems. but the non-working cookies seem different to those that are working (working: port 80-82, not working port 83). please notice the . as first letter.

ACLs I have disabled in the other working instances. In your screenshots I see, that the ACL-setup is the first step, before the connectivity check. In my setup, the sequence is reverse: first I have to setup the online-check, afterwards the ACL. maybe that makes a difference?

sessionport83
sessionport82_working
cookie-tab

mgrl commented Oct 3, 2017

okay, every cookie is set in the request, it seems. but the non-working cookies seem different to those that are working (working: port 80-82, not working port 83). please notice the . as first letter.

ACLs I have disabled in the other working instances. In your screenshots I see, that the ACL-setup is the first step, before the connectivity check. In my setup, the sequence is reverse: first I have to setup the online-check, afterwards the ACL. maybe that makes a difference?

sessionport83
sessionport82_working
cookie-tab

@foosel

This comment has been minimized.

Show comment
Hide comment
@foosel

foosel Oct 3, 2017

Owner

first I have to setup the online-check, afterwards the ACL. maybe that makes a difference?

That certainly explains things. And... argh... it's the translation that's at fault here! Your German "Zugangsbeschränkung" gets sorted after "Onlineprüfung", but the implementation of configuring the latter requires ACL to be explicitly enabled or disabled already... A stupid mistake, I'll fix that tomorrow by pinning the order :D

Owner

foosel commented Oct 3, 2017

first I have to setup the online-check, afterwards the ACL. maybe that makes a difference?

That certainly explains things. And... argh... it's the translation that's at fault here! Your German "Zugangsbeschränkung" gets sorted after "Onlineprüfung", but the implementation of configuring the latter requires ACL to be explicitly enabled or disabled already... A stupid mistake, I'll fix that tomorrow by pinning the order :D

@mgrl

This comment has been minimized.

Show comment
Hide comment
@mgrl

mgrl Oct 3, 2017

Hehe, great that we could track it down. Next stable is within reach ;)

mgrl commented Oct 3, 2017

Hehe, great that we could track it down. Next stable is within reach ;)

@foosel

This comment has been minimized.

Show comment
Hide comment
@foosel

foosel Oct 17, 2017

Owner

1.3.5 was released yesterday.

Owner

foosel commented Oct 17, 2017

1.3.5 was released yesterday.

@foosel foosel closed this Oct 17, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment