| Q | A
| ----------------- | ---
| Issue Type | Bug
| Deployer Version | 6.0.3
| Local Machine OS | MAC
| Remote Machine OS | ?
If you're reporting a bug, please include following information
deploy.phpWhen https://github.com/deployphp/deployer/blob/15274524b28c94e5967fa509a91680f599ddd23d/src/Ssh/Arguments.php#L128 equals to
With enabled option for verbose output -vvv.
[Deployer\Exception\RuntimeException (-1)]
The command "rm -f /srv/http/<username>/.dep/deploy.lock" failed.
Exit Code: -1 (Unknown error)
Host Name: acceptance
================
unix_listener: "<path with 104 chars>" too long for Unix domain
socket
Any news about this?
I think there is a bug in how the $controlPath length is tested against the maximum acceptable value (104) for two reasons:
At the beginning
$controlPath = "~/.ssh/deployer_$connectionData";
but the real socket path is something like this:
/Users/name.surname/.ssh/[email protected]
with the real home path instead of "~" and with a I-think-random-generated string at the end.
So, in my local machine, according to my username, I tried with a more realistic
while (strlen($controlPath) > 65);
and now the switch falls inside first case:
case 1:
$controlPath = "~/.ssh/deployer_%C";
and so deploy works correctly, because the socket generated now is something like:
deployer_e9749a1af24a8814ecceff249c6e338c61c1a117
that is shorter than the one created before.
Is it possible to fix this behavior? Thank you
Hi, yes it pissible to fix, kets use real path instead of ~
Hi :raising_hand_man:,
A quick fix for those who are stuck: you can disable ssh multiplexing by adding the snippet below into your deployer config:
set('ssh_multiplexing', false);
Also, since @giraz82 describes that this is about a socket. Would it be an option to place the socket file in another directory? /var/run would be preferred, but since we'll run into permission problems I'd say that /tmp would also suffice.
Writing the socket into a /tmp folder sounds like a terrible idea (security). I think it should be fixed in https://github.com/deployphp/deployer/blob/master/src/Ssh/Arguments.php#L130. This should probably take into consider the real path (as mentioned by @antonmedv), since the real path is the path that seems to be character counted.
Edit: Do I read the code correctly, that it's just simply checking if those hardcoded, non-evaluated strings are less then 104 characters long? It's not substituting those ControlPath variables, is it? 馃槦
It uses ssh itself to replase them.
@nvaken I'm wondering about the potential security flaw when placing a file in the /tmp directory. If you give the file the right permissions e.g. 0600 I'm convinced that no other user is able to read or write in the socket. Am I missing something ? :open_mouth:
@antonmedv how does generateControlPath() replace them with SSH before checking up on the length?
@nstapelbroek I'm not entirely sure what the security implications the /tmp folder brings. Though, there are some sources (only one I can find now is wikibooks.org) which imply that it would be a bad idea. Also, I'm not sure about showing files with the usernames / hostnames / ports in the /tmp folder. Though, might not be as bad as I initially thought?
@nvaken you are right, it doesnt check it using ssh. MAybe remove them from generateControlPath completely then?
Only thing I can think of is that the method could construct the paths itself? I do think the length check is valuable by itself, if it worked correctly. I might be able to create a patch later this week as a suggestion, not sure yet though.
Alright, it's been a bit more then a week. 馃槵
I've just debugged the generateControlPath() a bit. I have a hostname that is 62 characters long, on port 22. Therefor $controlPath (which is checked on string length) becomes: deployer_[a-hostname-of-62-characters]:22, which results in a strlen of 74 which is easily within the 104 limit. Although, this does not take in account that this file will appended with a connection hash which, strangely isn't actually appended to the file. Which might result in the following: deployer_[a-hostname-of-62-characters]:22.H0tQPCvXD48DN6lN, but again, even this should be within the 104 limit, so what's up?
UNIX_PATH_MAX, that's what's up. After a bit of Googling this defines the max length for the domain sockets, it appears that this might be a bit different per OS. As far as I can tell, this is 104 for Mac OS and 108 for Linux. So, still, not less than what we're checking on; 104. After some testing and manually creating control paths, I found out that this includes the entire, expanded, absolute path to the file.
So, I've been looking if it's possible to evaluate OpenSSH tokens like %C without starting an actual connection, but I've been unable to find a solution for this. Therefor, I think it'd be best if we just keep calculating, but keep in mind that;
Also, I noticed that most of the case's do not use the .ssh subfolder, which I guess is a mistake.
I've worked out above and will be submitting a pull request later.
It'll probably be good if someone reviews my fix in detail. I think I've done it right, though I have to say I'm not a SSH Multiplexing guru. Also, this fix includes an additional fix which adds ~/.ssh to all possible paths, which I think should be in place, though, please review.
Just when this pull requests came to merge, I noticed some redundancies in the cases. REst assured, nothing that would break stuff though.
This is fine...
case 1:
$controlPath = "$homeDir/.ssh/deployer_%C";
break;
Sure, no problem, but I think case 1 will almost always be shorter then 2
case 2:
$controlPath = "$homeDir/.ssh/deployer_$connectionData";
break;
This doesn't make any sense, especially since I've added /.ssh in this path and is now identical to 1. Nothing breaking though...
case 3:
$controlPath = "$homeDir/.ssh/deployer_%C";
break;
Sure, this is 5 characters shorter then 1.
case 4:
$controlPath = "$homeDir/.ssh/mux_%C";
break;
This is the same as 2.
default:
$controlPath = "$homeDir/.ssh/deployer_$connectionData";
I'd suggest removing case 2 and 3. Does that make sense to you @antonmedv? If so, I'll create a small update for that.
Yes, make sense. Maybe we can do some really short name in case of 3?
Not sure. I guess mux_ has been an acronym for multiplexer is quite short in itself. I don't think we are able to use _no_ prefix and %C is "only" 16 characters, so that totals to a 20 character filename which I think leaves plenty of space for the rest of the absolute path. Assuming a home directory structure of /users/[username]/ we leave room for a ~70 character username, seems plenty to me.
I'll try baking a update for the above today.
I guess this issue can now be closed @antonmedv?
Most helpful comment
Hi :raising_hand_man:,
A quick fix for those who are stuck: you can disable ssh multiplexing by adding the snippet below into your deployer config:
Also, since @giraz82 describes that this is about a socket. Would it be an option to place the socket file in another directory?
/var/runwould be preferred, but since we'll run into permission problems I'd say that/tmpwould also suffice.