Closed sroemer closed 10 months ago
... I added a
.*
at the beginning of the command as well, which makes this match quite easily - maybe too easy?. On the other hand I also didn't want to add the whole path within the regex.
Thanks for posting, ran into the same issues and used your solution!
@sroemer could you help me understand, what the scp -> sftp
command looks like so that it only works with .*
? Also, why would it match "too easily"? You still need to have the correct ssh key, right?
@cmacht
When you look at this whole entry, you see that this actually is a shell if condition, which handles 3 different cases. Actually I even did put that whole part in a separate script and used that script as the command in authorized_keys - but that's a detail.
#!/bin/bash
if [ -t 0 ]; then
# I recently added the additional --login to make bash load .bash_profile on ssh connects
bash --login
elif [[ ${SSH_ORIGINAL_COMMAND} =~ ^.*(scp|sftp|rsync|mysqldump).* ]]; then
eval ${SSH_ORIGINAL_COMMAND}
else
/home/isabell/gitea/gitea serv key-1 --config='/home/isabell/gitea/custom/conf/app.ini'
fi
So the condition checks the value of SSH_ORIGINAL_COMMAND
via a regular expression. If it matches, then the command will be executed via the eval
call. As I said in the original post already, for me this SSH_ORIGINAL_COMMAND
was /usr/libexec/openssh/sftp-server
in case of using scp
and therefore the regular expression did not match.
With my regular expression as it is now, the first .*
will match for the /usr/libexec/openssh/
part, the sftp
will match the sftp
string itself and the final .*
matches on the -server
part. But this regex also will match for any other command, which contains scp
or sftp
for example. That's what I meant with matching quite easily.
You still need to have the correct ssh key and so far I did not see any other issue with it too. In worst case (if ssh is called with a command different from the ones we want to match on, but our expression matches anyway), then we could end in the wrong path of the if condition again. Similar to what happened for us with scp
before the modification. The result would just be that something would not work again, because the wrong command is called.
Overall I think that's a quite theoretical problem, but I am not that deeply into SSH and don't know when and how this SSH_ORIGINAL_COMMAND is set.
Thanks for the fast and exhaustive reply, that makes sense! If you don't mind I would put this and my own issue #1578 into a PR.
Note, from painful experience: Be aware that key-1
is different for each new gitea user and your external script would need to take that into account.
Good point, yes. My script currently does not work for any other value than key-1
, but that could be changed easily by passing the key-X
value as a parameter if needed. Thanks for pointing that out and feel free to create a PR if you like to.
Obviously, you can also put that in the regex (just tried with success):
^(scp|/usr/libexec/openssh/sftp-server|rsync|mysqldump).*
...which is not the prettiest solution, but it gets rid of the problematic behaviour with the catch-all in front.
Yes sure, that's a way too. The downside is, that it only works if the whole path of the command is exactly the same. If for whatever reason with an OS Update or so, the path changes, then this will not work anymore.
Probably a good compromise would be to do it like this (but I didn't try that yet) :
^(scp|.*sftp-server|rsync|mysqldump).*
It keeps the rule strict for everything except for sftp-server
, which when used as a whole is quite unique as well.
Yes, you're right and that solution is much nicer. Tested it and it works. Thank you!
@sroemer As a follow-up, you might want to look at the much better solution proposed by @kimdiallo in #1627 - it's already running on my uberspaces.
A while ago I did set up a
gitea
instance on my uberspace and modified theauthorized_keys
file with following entry, as shown and described in thegitea
guide:command="if [ -t 0 ]; then bash; elif [[ ${SSH_ORIGINAL_COMMAND} =~ ^(scp|rsync|mysqldump).* ]]; then eval ${SSH_ORIGINAL_COMMAND}; else /home/isabell/gitea/gitea serv key-1 --config='/home/isabell/gitea/custom/conf/app.ini'; fi",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-...
In general this worked fine for me, with the exception that I could not copy files via
scp
to/from my uberspace. I now did analyze that problem by logging the SSH_ORIGINAL_COMMAND to a file.It turned out, that in case of using
scp
for me the command is:/usr/libexec/openssh/sftp-server
(sinceOpenSSH
9.0, thescp
program has been updated to useSFTP
). Therefore the regular expression^(scp|rsync|mysqldump).*
cannot match. My fix for now is to use^.*(scp|sftp|rsync|mysqldump).*
.I think this should be fixed in the guide, but I am not sure yet what would be the best regex to use here. While my approach currently works, I added a
.*
at the beginning of the command as well, which makes this match quite easily - maybe too easy?. On the other hand I also didn't want to add the whole path within the regex.