Updating DISPLAY with ssh and byobu - ssh

I have the following scenario:
In my work computer (A) I open a byobu (tmux) session.
Inside byobu, I open several terminals. Some of them are local to (A), but in others I ssh to a different computer (B).
I go home, and from my my home computer (C) I ssh to (A), run "byobu" and find all my sessions in (A) or (B).
This works perfectly, except for running X11 applications. I don't leave any X11 application running when I change computers, but just running "xclock" sometimes works and sometimes doesn't ("cannot connect to X server localhost:n.0").
I understand this depends on the DISPLAY variable, and that it would be set up such that X11 would connect to the computer where I ran "byobu" last before creating the session inside byobu, and that could be (A) or (C). My problem is that often I don't know how to fix a session that's not working any more. Sometimes I can just open another session (another tab in byobu) and use the value of $DISPLAY in other sessions, but that only works as long as the new session is open, and not always. In other cases I've been able to detach byobu (F6), re-attach it (run "byobu") and open a new ssh connection to (B), and then that one works, but not the already existing sessions.
I have read some documents like SSH, X11 Forwarding, and Terminal Multiplexers or How to get tmux X display to come back?, but it is unclear to me how they apply (if they do) to my situation. For instance, the .bashrc code of the former, should it be in (A), (B), or (C)?

UPDATE/EDIT I have found the correct way to do this. Simply type this in any of the byobu shells
. byobu-reconnect-sockets
and the DISPLAY environment variable for your new ssh connection, as well as SSH_AUTH_SOCK and several others that may be useful and dependent on the primary login shell (that which you do byobu attach-session -t session_name or for screen backend, byobu -D -R session_name or however you do prefer to do it).
This is all supposed to happen simply by pressing CTRL-F5, but I suspect that like me, your computer is intercepting the CTRL-F5 (for me, I am using iTerm on a Mac) and either doing its own thing with it, or sending the wrong control character sequence so byobu doesn't receive it properly. It's a bit more typing, but sourcing the shell script as indicated above will do the same thing as CTRL-F5 is supposed to do, and will do it for ALL byobu open shells in the session. The rest of my original answer below you can probably now ignore, but I'll leave it there in case it is in someway useful to someone perhaps for some other purpose.
Also, you can edit the byobu-reconnect-sockets script (it is just a shell script) and there are places to add additional environment variables you want updated, so really none of the below is necessary.
(original answer follows)
When you ssh in again and reattach your byobu sessions, it is likely that the ssh forwarded X11 display for your new ssh connection is not the same as the proxy display that initial ssh session created when you launched byobu. Suppose you ssh in for the first time and are going to start a new byobu session with many shells and perhaps many forwarded X11 windows, and this will all work fine, because that first ssh shell sets the DISPLAY environment variable to what it is listening on for X11 connections. This might be something like
[~/]$ printenv DISPLAY
localhost:11.0
all shells started by byobu (and tmux or screen on the backend) are going to inherit the setting of all the environment variables that were set when byobu was initially launched, ie, the X11 display that was forwarded for your user for your first ssh connection.
Then you detach your byobu session and go home, and ssh back in. But this time you get a different X11 display, because some other user has localhost:11.0. In your new ssh session that you started at home, the value of DISPLAY might be localhost:14.0 (say). For X11 forwarding through this ssh connection, X11 clients need to connect to the ssh X11 proxy at display localhost:14.0, not localhost:11.0. You will likely not have the authorization keys for localhost:11.0 at that point, someone else will, or worse, if they have disabled X authentication, the X11 windows you are trying to open are going to start showing up on their screen. All you need to do to make it work, is this -
detach byobu
you should now be in the current ssh shell. Do printenv DISPLAY and note the value shown (or copy it)
reattach byobu
In any shell you want to use X11 in, do export DISPLAY=localhost:14.0 (in this example it'd be that value, you'll use whatever value you get for #2 in your case)
X11 will now forward through ssh to your screen as you expect
The catch - you have to do this in every byobu shell that is open separately if you want to use X in that shell. To my knowledge there is no way to set it in all shells except I think there may be a way to run any arbitrary command in all shells at the same time, but I don't know the key sequence to do that off the top of my head.
the annoying - you have to do this every time you detach and disconnect your ssh connection, and then reconnect with ssh and reattach your byobu, as it is likely the DISPLAY environment variable in the ssh shell has changed, but your shells either have what was set for DISPLAY when byobu was initially started, or whatever you have last set it to.
Even if you open new shells in byobu in some later ssh connection, those shells will still inherit the DISPLAY environment variable setting that was set when byobu was first started, all the way back to your first ssh connection. You have to do this with new shells too.
This annoys me constantly and I'd love to take the time to develop some hack of some kind to at least make this less tedious, and best of all would be to have it done along with ctrl-F5, which effectively does exactly all this, but for some other things you often want to reconnect with your new ssh session, especially SSH_AUTH_SOCK for ssh-agent.

Related

Raspberry Pi Zero no data over SCP at low data transmission

I have a Raspberry Zero connected to a SIM7600G-H 4G HAT with a camera module connected. I want to use it as a webcam, who makes a picture in a defined cycle and send's it via scp to a web server who display it on a homepage.The created shell script is started via a CRONJob every 2 hours.
The whole setup works very well if I have a good, powerful SIM connection. However, as soon as I operate the setup at the desired location, a strange behavior appears.
At the location where I run the webcam I only have a relatively poor 3G connection, if I run the scp command from a connected laptop it works fine. I can therefore assume that the problem has nothing to do with the SIM module.
The Raspian shows two peculiar behaviors.
Even though i created a key and gave it to the webserver, every now and then it wants me to enter the password when i run the scp command.This does not happen when I connect directly to the webserver via ssh.
The first few images the raspian loads without problems using scp command on the webserver, but then suddenly it does not work anymore.
I send two pictures each. I replace one with an existing one on the web server. This is the image that is displayed on the homepage and another one I put in an archive folder named after the timestamp. It looks like this:
scp foo.jpg <username>#webserver:dir/to/folder/default.jpg
FILENAME=`date +"%Y-%m-%d_%H-%M-%S"`
scp foo.jpg <username>#webserver:dir/to/archive_folder/${FILENAME}.jpg
Because of the password issue I downloaded an additional service called sshpass and added in addition to the scp command the following command:
sshpass -p <password>
However, it seems like the issue is not related to sshpass since it also happens if I try it only with the scp command and enter the password by my self.
At the end for the "new file" which goes into the archive folder, the raspian creates the filename at the web server, but he does not transmit the data of the file. At the end, the file remains empty.
The file which should be replaced "default.jpg" is not touched at all.
I tried to find out what happens via the debug output. But there is no useful information. It always stops with the line who shows the transmission state and with 0% and 0KB/s.
I have now spent several days on a solution. I have also already taken it home and everything has suddenly worked smoothly again. But as soon as I mounted it there again, the problem reappeared.
Does anyone know of a bug with the raspberry zero that it can no longer transfer scp files when the data transfer rate is low? One image is about 300kb and my laptop takes about 20 seconds to transfer over the same connection as the one from the Raspberry.
After countless attempts, my simplest solution was to set up a cronjob, which restarts the raspberry shortly before it takes a photo for the webcam. It then searches for a new network and finds it very reliably.

Running command after SSH forced command

I configured my Raspberry Pi SSH-server to only accept ssh keys when logging in. Really clever I thought, until now.
The thing is, I've added a forced command for one key like this to authorized_keys:
command="cd /home/pi/Sites/" ssh-rsa [bla bla bla] [my comment]
And when trying to log in now, it says just
Connection to MYSITE closed.
What I presume is that the forced command is being run and after that no interactive shell is being launched and therefore the connection is closed. Is there any way to connect anyway and undo the changes I've done to the authorized_keys-file?
What I presume is that the forced command is being run and after that no interactive shell is being launched and therefore the connection is closed.
Exactly.
Is there any way to connect anyway and undo the changes I've done to the authorized_keys-file?
No. This is a feature. If you would be able to override this, it would be going around security policy that you defined (well ... this exactly does not make a lot of sense).
As already pointed out, if you don't have different authorized key, different user with authorized keys or passwords, you will have to get to the remote location and modify that file physically on the SD card.
For the next time, if you want to cd to some directory and start interactive bash, you will need
command="cd /tmp/;bash" s

Windows / Linux automatic key exchange

I have a build box, which I use to make continuous builds as well as run nightly unit tests. I'm using Jenkins to do by builds/unit test scripts, which is running on a windows box because our compiler is windows based.
One of our enterprise solutions uses Python code with rabbitmq for exchanging messages for syncing specific database tables over a faulty network. I have unit tests to help verify that updates are happening correctly.
In order to unit test the Python updates, I need to be able to stop some services running on my Linux box, then restart them after I update the python code. I setup a key exchange between my Windows box and Linux box, so that I don't have to put a password in the batch script.
When I'm remoted into the windows box, I can successfully run the batch file, which uses plink commands which rely on the key exchange and putty's pageant (which is running in the background). e.g. I use plink to execute commands on the Linux box from command line in my batch file. However, when I try to run the batch file from Jenkins, the batch file doesn't work properly because it is prompted for the SSH password when trying to run the plink commands.
I believe my current issue can be summarized by two issues, which I'm hoping can be verified and rectified:
I think Jenkins may be running as a different user or using different system credentials so it's not able to connect like the logged in user can. If this is the case, what would I need to do, to get it so that Jenkins can run the plink commands properly without being prompted for the password.
Pageant looks like it needs to get a password typed in every time the computer restarts. My research unearthed ways to put Pageant in startup, so you get prompted when you first login, but I need this to be automatic, like how I can on Linux boxes. If Windows reboots because of a Windows update, then the unit tests would fail as they won't be able to connect to the Linux server. Sure this only happens once a week, but over the course of a year it'll be very annoying.
What can I do to solve the above two issues? If there is a good alternative to putty for the automatic key exchange between Windows and Linux, I'd be interested in hearing about it (I would prefer to stay away from Cygwin with OpenSSH, but might go down this route if the above can't be rectified).
I use plink on my Windows Jenkins box to communicate with Linux on daily basis, there is no problem with it.
Like you theorized, Jenkins runs under it's own user (Windows default, I think, is SYSTEM user), which is different than your logged in session, even if you login as Administrator. Your authentication key is stored in your (Administrator or otherwise) profile directory
What you need to do is use Pageant to export your key as ppk file, then supply the path to this ppk file with plink:
plink -i "C:\path\to\id.ppk"
Looks like there is a simpler way to do what I'm trying to do, Jenkin's plugin https://wiki.jenkins-ci.org/display/JENKINS/Publish+Over+SSH+Plugin

Limit SSH - bash with no commands

So I have been working on this for some time. Would like to know if there is a better way or if I am on the right track.
I would basically like to allow some users to login to my server via SSH and then have a squid tunnel via that SSH connection.
The tricky part however is that I dont want these users to be able to execute ANY commands. I mean NOTHING at all.
So at this stage I have setup a Jail via - jailkit. The specific user is then placed in the jail and given the bash shell as a shell.
The next step would be to remove all the commands in the /jail/bin/ directories etc so that they are not able to execute any commands.
Am I on the right path here? What would you suggest?
Also...I see that it will give them many command not found errors...how do I remove these.
Is there any other shell I could look at giving them that would not let them do anything?
You could set their shell to something like /bin/true, or maybe a simple script that will output an informational message, and then have them logon using ssh -N (see the ssh manual page). I believe that allows them to use portforwarding without having an actuall shell on the system.
EDIT:
The equivalent of ssh -N in PuTTY is checking the "Don't start a shell or command at all" checkbox in its SSH configuration tab (Connection->SSH).
EDIT2:
As an alternative to this you could use a script that enters an infinite sleep loop. Until it is interrupted using Ctrl-C the connection will remain alive. I just tried this:
#!/bin/sh
echo "DNSH: Do-Nothing Shell"
while sleep 3600; do :; done
If you use this as a shell (preferrably with a more helpful message) your users will be able to use port-forwarding without an actual shell and without having to know about ssh -N and friends.

Prevent interactive ssh prompts

I have an ssh script that uses a local key for login to the remote host - nothing too exciting there. The key is passworded and I usually add it to an agent to avoid prompting.
Occasionally I run the program before the agent is running and it will hang waiting for the unlock phrase. In such cases, rather than prompt interactively, I want the command to simply fail.
Anyone know if there's an option for this?
Sure is.
ssh REMOTE_HOST -o "BatchMode yes"