-
Notifications
You must be signed in to change notification settings - Fork 50
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
401 Unauthorized error on a request to "/1.5/{uid}/*" when using a node-url with added path like "http://localhost/fxs" #1217
Comments
I think what's happening is that, when your browser sends a request to your Sync node, it generates a MAC using the path that includes the The whole flow would look like:
This is expected behavior, but you may be able to work around it using a different Apache configuration. |
I already had the same idea and modified my Apache config to include the
The problem with that is, that the actix webserver is expecting syncstorage-rs/src/server/mod.rs Line 81 in 04b2437
cfg_path is used to assemble the api endpoint path. This function (syncstorage-rs/src/server/mod.rs Lines 52 to 60 in 04b2437
/1.5/your_uid prefix which is used by actix as the api endpoint. So appending my /fxs will not work :(
I'm still trying to wrap my head around rust syntax and how everything is connected to better help to find a solution. As far as i understand the source code, https://github.com/mozilla-services/syncstorage-rs/blob/aa93312a1c1e7c1e102ad38a1ff935518e437cb4/src/web/extractors.rs and https://github.com/mozilla-services/syncstorage-rs/blob/04b2437816b2b653f0143fa333d1e61230466cb3/src/web/auth.rs are used to generate and check the hawk secret + mac during a request. The actual path of the node from the database is never used besides sending it to Firefox so it knows how to contact the storage system. Any other ideas? |
I now tried the server again on my dedicated server(public IP) without the My Apache config:
Syncstorage config is the same. Api endpoint for the node inside the DB is Is it possible to add a parameter to the config to give a public url like the old syncserver had? Or is there a possibility to run the server with HTTPS without a proxy? |
@LuckyTeran I think you have to prevent ssl offloading. so the origin server understand that the request is made over https. Another thing i have to do was to allow all origins by adding |
This would probably be the path we'd take to support reverse proxies. In the meantime, I've added a ticket to explore supporting HTTPS directly on the server it self to eliminate the need for a reverse proxy. |
Home servers very commonly use path prefixes rather than hostnames or ports to differentiate services, e.g.:
And they most commonly put all their services behind one proxying webserver, for maintenance, security, robustness, centralised logging and centralised access control. Why try and set up 10 different services and all require them to support HTTPS, when you can have a single webserver like Caddy/nginx/httpd to handle the HTTPS and then reverse-proxy, rather than expecting every service to implement HTTPS (and risk that any one of them has an flaw that leaks a private key) So in short, rather than try to eliminate the need for reverse proxies, support reverse proxies. Support what SyncServer-1.5 had:
No need to guess what the request's absolute URL might be and get it wrong and screw up authentication. Just let the user tell you the absolute URL in the config file. |
As syncserver doesn't support configuring a path prefix, I made it support one by hardcoding it in the source. The public URL is e.g. https://home-server.example.com/firefox-sync (and therefore the tokenserver URL is https://home-server.example.com/firefox-sync/1.0/sync/1.5). This code adds the necessary prefix for authentication: diff --git a/syncserver/src/web/auth.rs b/syncserver/src/web/auth.rs
index 9153d38..0a7af57 100644
--- a/syncserver/src/web/auth.rs
+++ b/syncserver/src/web/auth.rs
@@ -197,6 +197,7 @@ impl HawkPayload {
Utc::now().timestamp() as u64
};
+ let path = "/firefox-sync".to_owned() + path.as_str();
HawkPayload::new(header, method, path.as_str(), host, port, secrets, expiry)
}
} Along with ensuring that the reverse proxy passes If the public URL is not on the standard port (80 for http, 443 for https) then this has to be passed in Caddy config example: handle_path /firefox-sync/* {
reverse_proxy localhost:8000 # implicitly sends X-Fowarded-Host and X-Forwarded-Proto
} Apache config example: <Location "/firefox-sync">
ProxyPass http://localhost:8000 # implicitly sends X-Fowarded-Host
RequestHeader set X-Forwarded-Proto "https"
</Location> nginx config example: location /firefox-sync {
proxy_pass http://localhost:8000/;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto "https";
} |
Hmm... adding an optional path prefix defined from a preference sounds like a pretty good idea. |
TL;DR:
When i add a node into the database that has a added path like "http://localhost/fxs" auth seems to fail and the server returns 401. Without the added path everything works. Even changing different hostname (like test.tld) or port does not produce an error. It seems somehow the url is used in auth but not the hostname?
Long version with steps i tried to find and diagnose the error:
Since #1189 is fixed i was able to run a working local instance of syncstorage_rs. I then tried to deploy syncstorage_rs on a dedicated server with public ip and for added security behind Apache2.4 as proxy. The connection with the tokenserver part (/1.0/sync/1.5) works without problems but every time firefox tries to connect to the syncstorage part (/1.5/{uid}/*) the server returns 401 as status. I suspected that apache as a proxy is somehow causing issues.
After investigating further i could replicate the error in a local setup with the following configs:
firefox-syncstorage.toml:
apache vhost:
When i directly connect to syncserver_rs with Firefox ("identity.sync.tokenserver.uri=http://locahost:8000/1.0/sync/1.5") and add a node into the tokenserver_rs database with "node=http://localhost:8000" everyting works as expected.
Here is the relevant part of the log of syncstorage_rs (everything after the "/1.5/13/storage/meta/global" request is removed to shorten the log to be readable):
If i connect with "identity.sync.tokenserver.uri=http://locahost/fxs/1.0/sync/1.5" with a modified node db entry "node=http://localhost/fxs" and over Apache as a proxy, i get the 401 error on the request to "/1.5/13/info/collections". This should mean that Apache is forwarding the request correctly to syncstorage_rs.
Here is the log of syncstorage_rs:
RUST_LOG="trace" /usr/bin/firefox-syncstorage --config=/etc/firefox-syncstorage.toml
The logs tell me that Apache strips the "/fxs" part from the path correctly and forwards the requests to syncstorage_rs.
To narrow it down more i removed the path "/fxs" from the apache config and tried to connect with "identity.sync.tokenserver.uri=http://locahost/1.0/sync/1.5" and node db entry of "node=http://localhost" over Apache and it worked.
Here are the syncstorage_rs logs:
RUST_LOG="trace" /usr/bin/firefox-syncstorage --config=/etc/firefox-syncstorage.toml
At that point i thought that somehow the hostname and/or url is used in auth so i added a host entry "test.tld" to point to my lan ip (192.168.x.x) instead of localhost (127.0.0.1). I ran the same test this time with "identity.sync.tokenserver.uri=http://test.tld/1.0/sync/1.5" and node db entry of "node=http://test.tld" and it still worked.
Here is the log:
RUST_LOG="trace" /usr/bin/firefox-syncstorage --config=/etc/firefox-syncstorage.toml
It seems the hostname and Apache as proxy are not the problem. Only if i add a path like "/fxs" ("identity.sync.tokenserver.uri=http://locahost/fxs" with node db entry "node=http://localhost/fxs") i get the auth error.
I started to capture the traffic with wireshark to check the requests and the auth data. The value of the Authorization header on a request to "/1.0/sync/1.5" is always exactly the same in every constellation (Authorization: Bearer xxx). The Authorization header on a request to "/1.5/13/info/collection" is different in every constellation, but that is expected because the hawk-id includes the node-url (every other field inside the ID is identical except some binary part at the end). I did not see anything else, and I don't know enough about hawk to judge if the auth strings are correct :(
Out of options i tried other combinations:
The tokenserver url inside firefox apparently does not matter. This further shows that Apache as proxy is not a problem, only using a node url like "http://localhost/fxs" is somehow causing the auth to fail. I could not find in the code if and where the node url gets used in the auth.
Maybe this is related to #671 ?
I don't know enough to further narrow down where exactly the error comes from but i need the added "/fxs" path in my setup so i hope someone else is able to find the problem or point me in the right direction where to look or what i'm doing wrong.
The text was updated successfully, but these errors were encountered: