-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Using exec -a
in gitea/gitea:dev
container broke SSH passthrough access
#18117
Comments
gitea/gitea:dev
container breaks SSH passthrough accessgitea/gitea:dev
container broke SSH passthrough access
Can you check what happens to your |
This is using SSH passthrough, so The docs for instance say that # SSH pubkey from git user
ssh-rsa <Gitea Host Key>
# other keys from users
command="/app/gitea/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty <user pubkey> The |
@zeripath I updated the comment, how do you think about these two solutions? |
gitea/gitea:dev
container broke SSH passthrough accessexec -a
in gitea/gitea:dev
container broke SSH passthrough access
Can we have a way to set our own path to the executable instead of I also don't like cluttering up |
That's a more complex design problem. Now, the SSH pass-through uses (shares) Gitea's authorized_keys file on host side, that's the key problem. If you can separate the two authorized_keys files (eg: AuthorizedKeysCommand), then the problem could be resolved. |
A combined The real issue I think is why there is an executable required at |
There are two One is the bridge script on your host, it just executes the real gitea app inside docker. However, the guide only uses one shared authorized_keys, there is only one path for both gitea executables. user -> git@host -> read authorized_keys -> command gitea app (bridge) -> git@docker -> read authorized_keys -> command gitea app (real) |
Thanks for clarifying. In that case, Working example: [root@remote-server .ssh]# cat authorized_keys
# gitea public key
command="GITEA_KEYNUM=10 ; GITEA_BIN=\"/app/gitea/gitea\" ; SSH_PASSTHROUGH_PORT=\"2221\" ; passthrough_required() { ! [ -f \"$GITEA_BIN\" ] ; } ; gitea_ssh_command() { passthrough_required || { \"$GITEA_BIN\" \"$@\" ; return $? ; } ; ssh -p \"$SSH_PASSTHROUGH_PORT\" -o StrictHostKeyChecking=no [email protected] \"SSH_ORIGINAL_COMMAND=\\"$SSH_ORIGINAL_COMMAND\\" \\"$GITEA_BIN\\" $@\" ; } ; gitea_ssh_command --config=/data/gitea/conf/app.ini serv \"key-$GITEA_KEYNUM\"",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict ssh-rsa <SOME_SSH_PUB_KEY> [user@hostname]
# gitea public key
command="GITEA_KEYNUM=12 ; GITEA_BIN=\"/app/gitea/gitea\" ; SSH_PASSTHROUGH_PORT=\"2221\" ; passthrough_required() { ! [ -f \"$GITEA_BIN\" ] ; } ; gitea_ssh_command() { passthrough_required || { \"$GITEA_BIN\" \"$@\" ; return $? ; } ; ssh -p \"$SSH_PASSTHROUGH_PORT\" -o StrictHostKeyChecking=no [email protected] \"SSH_ORIGINAL_COMMAND=\\"$SSH_ORIGINAL_COMMAND\\" \\"$GITEA_BIN\\" $@\" ; } ; gitea_ssh_command --config=/data/gitea/conf/app.ini serv \"key-$GITEA_KEYNUM\"",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict ssh-rsa <user1_SSH_PUB_KEY> user1@localhost
# SSH pubkey from the Host machine's git user
ssh-rsa <gituser_SSH_PUB_KEY> Git Host Key
# Other keys from users of Gitea
command="GITEA_KEYNUM=1 ; GITEA_BIN=\"/app/gitea/gitea\" ; SSH_PASSTHROUGH_PORT=\"2221\" ; passthrough_required() { ! [ -f \"$GITEA_BIN\" ] ; } ; gitea_ssh_command() { passthrough_required || { \"$GITEA_BIN\" \"$@\" ; return $? ; } ; ssh -p \"$SSH_PASSTHROUGH_PORT\" -o StrictHostKeyChecking=no [email protected] \"SSH_ORIGINAL_COMMAND=\\"$SSH_ORIGINAL_COMMAND\\" \\"$GITEA_BIN\\" $@\" ; } ; gitea_ssh_command --config=/data/gitea/conf/app.ini serv \"key-$GITEA_KEYNUM\"",no-port-forward,no-X11-forwarding,no-agent-forwarding,no-pty <user pubkey> and so on. FYI: I made it more verbose so you can see how different parts can be edited, particularly |
Gitea is not the reason for requiring anything on the host - your decision not to pass every ssh request directly to Gitea is the reason you're needing to consider this. SSH is not the same as HTTP. So you have to make some decisions about how you're going to arrange communication between your host ssh and the Gitea ssh. This is not our fault and claiming that something isn't the docker way isn't helpful. As far as I have been able to find openssh and the ssh protocol is not built to allow routing like you want it. Especially not the way it has to be used for git. Gitea did not invent the use of the common git user for ssh. Git didn't do that either. Having a common user using authorized_keys to identify the real user dates back to at least the SVN days but likely CVS days too. This precedes docker by some decades. One suggestion which people found simplest was to use and munge the authorized_keys file so that was suggested, however Gitea has had a keys command which fits with the authorized keys command output. Others have found that a script that calls docker exec works better. You may want to try that instead. However moaning about how X or Y isn't the docker way is NOT going to induce me to spend any time thinking about your problem. In your case simply just add a symbolic link or replace the /usr/local/bin/gitea with what you need it to be in the keys file using a regular expression. |
You don't seem to understand this thread. I posted a solution which sacrifices nothing and solves the issue. There is little to think about. Tweak a bit and merge. Issue resolved. I can't help it if you choose to be stubborn or if you do not understand this thread. The Gitea documentation explicitly supports SSH passthrough. A commitment has been made to support SSH passthrough. You cannot now moan when users expect SSH passthrough not to break. Also try removing support for SSH passthrough, see very quickly just how many people will 'moan'. I'm not sure if you've ever used Gitea docker before, because it becomes very clear why SSH passthrough is needed once you have. |
Upgrade to 1.16.0-rc1 broke the docker SSH passthrough for me as well. |
Thanks for the fix @jpraet! 🥳 I think this should either be fixed or be mentioned in the release notes! |
Thanks for the workaround/fix - I'm back in business! |
@zeripath how do you think, which action should we take?
|
@Myridium would you kindly be more civil and less insulting. Please do not assume that I am an idiot and that I do not understand how SSH passthrough is supposed to work. If you want the host to listen to SSH requests and then passthrough certain SSH requests then by definition the host has to know something about the docker. The simplest solution to this is to simply use the same authorized_keys file that the docker would produce and just shadow the binary that was on there. Unfortunately #17846 made a change that resulted in the binary was being referred to was changed from I do not understand how your proposal would prevent the host from having to have some knowledge of the docker. As I state above it is simply not possible to have ssh passthrough and have the host not know something about the docker - this is by definition. You state this as a your example:
Essentially you are suggesting that the GITEA_KEYNUM=10
GITEA_BIN="/app/gitea/gitea"
SSH_PASSTHROUGH_PORT="2221"
passthrough_required() {
! [ -f "$GITEA_BIN" ] ;
}
gitea_ssh_command() {
passthrough_required || {
"$GITEA_BIN" "$@" ; return $? ;
} ;
ssh -p "$SSH_PASSTHROUGH_PORT" -o StrictHostKeyChecking=no [email protected] \
"SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" \"$GITEA_BIN\" $@" ;
} ;
gitea_ssh_command --config=/data/gitea/conf/app.ini serv "key-$GITEA_KEYNUM" Which you are more than free to set gitea to produce by setting the However, this is NOT preventing the host from having knowledge of the docker. In fact it's worse - the docker now has to have knowledge of the host because your passthrough_required function requires finding that file is not present on the host. You can play around more and more with functions and environment variables but in the end you may as well just shim the binary using a scrip, because fundamentally the host still has to have knowledge of the docker to get the .ssh/authorized_keys template etc. Whilst it would be possible to use Fundamentally I do not see any way to escape the host knowing something about the docker. Making the docker depend on the host is not really a solution as far as I can see. |
@wxiaoguang I vote just update the documentation and we need to add a BREAKING to #17846. We need the I should add that this kind of unexpected breaking behaviour is exactly why I wanted to use the LDFLAGS approach instead (#17501). Those affected just update your scripts to be at /usr/local/bin/gitea OR change your SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE. |
I already gave this exact same solution the day I posted this bug:
|
I can not get the point why the script can not do its job without |
@zeripath
As you said yourself,
I'm not 100% sure what you mean. But as I said in my comment, this is just an example. A more robust solution in gitea would do something like write a randomly-named file to the filesystem in the However, in most cases, the kind of example I provided would suffice. The edge cases where it would fail are those where the host does in fact have an As we know, users running docker may not have the administrative permission required to create or to access a directory like Based on these considerations, it seems sensible to me to merge something quite similar to the example I gave, without worrying about the possible clash between host and container. Of course a dev note could be made for posterity, in case it becomes an issue in the future. |
Unfortunately go-gitea#17846 broke the SSH documentation as the authorized_keys now uses /usr/local/bin/gitea instead of /app/gitea/gitea. This PR updates this documentation and provides documentation to offer multiple options including docker-shells and ssh-shells to help avoid this problem in future. Fix go-gitea#18117 Signed-off-by: Andrew Thornton <[email protected]>
Gitea Version
Gitea version 1.16.0
How are you running Gitea?
gitea/gitea:dev
docker.Description
Gitea Docker now uses
exec -a "$0" ...
in/usr/local/bin/gitea
, so AppPath is resolved to/usr/local/bin/gitea
now.Before, the AppPath is
/app/gitea/gitea
.The AppPath is used inside authorized_keys file and shared on both container and host side.
This can introduce some problems:
/app/gitea/gitea
, which misleads users. https://docs.gitea.io/en-us/install-with-docker/#ssh-container-passthroughThe easy fix is using
exec ....
instead ofexec -a "$0" ...
(Is there any Pros of usingexec -a
?)Or Gitea should update the document and mark this behavior as breaking.
by @wxiaoguang: personally I prefer to keep 1.16 behavior, otherwise it's too strange to force users creating a
/app/gitea/
on their host.I solved this issue (at least temporarily?) in the midst of writing a bug report. But it was caused by an (unknown) bug in
gitea
which may or may not be resolved. I'm going to leave this bug report here because the cause is unknown to me and it could happen again (e.g. when adding a key) and in case it helps others troubleshoot similar problems in the future.The short of it: some update to the
gitea/gitea:dev
container caused thegit
user'sauthorized_keys
file to rewrite/app/gitea/gitea
to/usr/local/bin/gitea
, after I pulled thegitea/gitea:dev
container for the first time in about a month or 2, and relaunched the image viadocker-compose.yml
. I am reasonably sure that thegitea
'database version' made a jump from189
to205
when I did this (maybe that is helpful information).The issue
Last time I pulled the
gitea/gitea:dev
container, it was somewhat ahead of1.15.8
. I pulled thedev
version because it contained an unmerged bug fix regarding FIDO and 2FA.Since pulling the
gitea/gitea:dev
container again yesterday (I forgot I had thedev
tag set), I can no longer access the SSH passthrough, with this error:Troubleshooting and resolving
This error makes no sense to me, as I run on the remote server::
Showing that
/usr/local/bin/gitea
is readable and executable by everyone.Gitea is configured to run with a
git
user like so in thedocker-compose.yml
:Naturally, I try downgrading to a previous version of
gitea
. I think that my oldgitea/gitea:dev
image before pulling was compatible with1.15.8
(I left that comment you see in thedocker-compose.yml
). So I try reverting to that version.gitea
fails to start however, and thedocker logs container_gitea
shows:Uh oh. I'm not messing around with a database downgrade, especially when the version difference looks so enormous. So I'm going to have to try to rectify this issue with the container I have. (I do
docker tag gitea/gitea:dev gitea/gitea:peg
and change thedocker-compose.yml
to use this. I don't want to be ondev
anymore and when a new compatible fixed version tag becomes available, e.g.gitea/gitea:1.16
, I will use that.)Now I try simply
ssh
ing into the server to see what happens:So now I
docker stop
thecontainer_gitea
entirely, and I tryssh
ing again and get the same result as above! Okay, so something wrong with the SSH passthrough configuration then?I check and see that
/app/gitea/gitea
onremote-server
is readable and executable by everything (as is/app
and/app/gitea
). Yes, that's fine.Then I try
ssh
ing using a local user:Then with the
git
user whichgitea
runs as: this works.I don't understand. Here are the contents of
/app/gitea/gitea
:So now I check
remote-server:/home/git/.ssh/authorized_keys
; this is where the magic is supposed to happen which forwards requests togitea
. Bingo. Here's the problem:I only ever added keys to gitea using the web interface, and I didn't do anything like
ssh-copy-id git@remote-server
to copy keys manually to that user.Thankfully gitea seems to keep backups of
authorized_keys
. I copied over one of the two most recent backups (same minute) sitting in the same directory next toauthorized_keys
. It looks like this:After replacing
authorized_keys
with a copy of this backup,ssh
andgit <command> git@remote-server
are now working.The text was updated successfully, but these errors were encountered: