Socat exclusive lock to PTY - locking

I would like only one process to open the PTY device created by socat.
I used the following to create my_ser device, but it can be read / written by multiple processes.
socat -t 0 INTERFACE:my_nw,type=2 PTY,mode=0777,rawer,link=/dev/my_ser
I tried to used
socat -t 0 INTERFACE:my_nw,type=2 PTY,mode=0777,rawer,link=/dev/my_ser,ioctl-void=0x540c to use the PTY exclusive lock (TIOCEXCL), but it does not work.
I can see the IOCTL being executed, but with no effect.
I am running on Ubuntu machine

I understood now the TIOCEXCL flag in more detail. The application opening the PTY terminal should use this flag to obtain the exclusive lock. If we use it during PTY creation in socat command, it has no effect. But it does not give any error as well.
Thus the application should call the ioctl flag and it should be removed from here.

Related

run noninteractive ssh command in background immeidately suspends the job

(1) I can run the following command and get the output successfully
ssh server hostname
(2) If I run it in background (not to background hotname, but to background ssh)
ssh server hostname &
and do nothing other than wait, I can get the output
(3) However, if before it finishes I type any key to the terminal, the job immediately turns into suspended state
[ZSH] suspended (tty input) ssh server hostname
[BASH] Stopped ssh server hostname
What is the reason for this and how to solve it?
I just use hostname as an example. You can try using sleep 5 instead if the program returns too quickly. The actual program I want to run lasts for minutes.
Use ssh -T -f server hostname as the manual page states:
-f requests ssh to go to background just before command execution.
This is useful if ssh is going to ask for passwords or
passphrases, but the user wants it in the background. This
implies -n. The recommended way to start X11 programs at a
remote site is with something like ssh -f host xterm.
If the ExitOnForwardFailure configuration option is set to “yes”,
then a client started with -f will wait for all remote port for-
wards to be successfully established before placing itself in the
background.
-T Disable pseudo-tty allocation.

Why use -T with ssh

To test ssh I read you need to use something like ssh -T user#domain.com:
According to man ssh:
-T Disable pseudo-terminal allocation.
-t Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote
machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty alloca-
tion, even if ssh has no local tty.
but I'm still not clear, even after reading this, what the purpose of using -T is when testing SSH.
I read up on pseudo-terminals (https://linux.die.net/man/7/pty) but that didn't seem to help.
To have interactive prompt in your ssh shell, you need to have allocated PTY also on the server side. It is done automatically when you call ssh host.
When you allocate this PTY on server, then your local terminal and the remote one are exchanging some additional messages (Terminal control characters), which give the remote shell information about the size of your local terminal, the remote can update title of your window and so on. This is something you really don't want when you want to transfer files or just pass the output "as it is". It would modify that and you would get generally something else. Again, this is done automatically in case you use scp or just noninteractive script as ssh host my_script.
So far good. You don't need the switches. But things might not be always so simple.
You might want to invoke some interactive shell as a command, for example ssh host /bin/zsh. This would work, but it will not be interactive. In this case, you need to use the -t switch to make it working properly: ssh -t host /bin/zsh.
The same thing can go other way round. You might have server set up, that it will give you some output regardless the command you ask for. In that case, you really don't want to mess it up with any terminal control characters and then you might want to use ssh -T host to avoid this clutch.
You can consider the -T also as the way to safe resources on server and as some "second line of defense". You can disable the TTY allocation in the server configuration, but what if ...
The most common use case for the -T switch is
ssh -T git#github.com
to verify that you have set up your ssh keys properly to authenticate to github.

Causing SSH to Time Out (client side)

I have a little Raspberry Pi that I'm playing with. I've got it running headless, and I need to make it forward one of its ports to a remote server when certain conditions are satisfied.
However, I don't want the connection to sit indefinitely until the server closes it. Is there a way to close an SSH connection (from the client, I have no root to the server) after a certain amount of time? Ideally I'd do it directly via the ssh command, but I'm writing in Python 3, so if there's a way to do this in Python, then I'm all ears.
In your /etc/ssh/sshd_config:
ClientAliveInterval <time interval in seconds>
ClientAliveCountMax 0
So using 300 in the first directive will kick the connection after 5 minutes idle. You'll need to restart sshd to make it take effect.
try ssh -o ServerAliveInterval=10 server.org
Unless you run ssh with the "-N" option, it normally launches some kind of command or shell on the remote system (the Pi in this case). Ssh disconnects when this remote command exits.
If you're running ssh just to create some port forwards, you may be running with "-N", or you may be letting the ssh session sit at a command prompt. Instead, you could launch a command on the Pi which exits after the desired period of time. You could use the sleep command, for example:
ssh -Lwhatever -Rwhatever user#pi "sleep 3600"

why is the `tcgetattr` error seen when ssh is used for dumping the backup file on another server?

I want to dump a tables backup on another server and I am using ssh for doing it.
when I run the below command, it gives an error but dump file is copied to destination.
mysqldump -u username -ppassword dbname tablename | ssh -t -t servers_username#domain_name 'cat > /tmp/bckp.sql';
tcgetattr: Invalid argument
If I press CTRL+c then it appends error message with Killed by signal 2.
Why is this error?
I've seen this error when forcing pseudo-terminal allocation using ssh -t -t or ssh -tt.
The tcgetattr function is used to look up the attributes of the pseudoterminal represented by a file descriptor; it takes a file descriptor and a pointer to a termios structure to store the terminal metadata in. It looks to me from the stub code in glibc that this error represents a null pointer for the termios struct. I am not sure whether these same error handling semantics are in place for the platform-specific implementations of tcgetattr.
If you want to suppress this error, invoke ssh like so:
ssh 2>/dev/null
This will redirect STDERR to /dev/null; you won't see the error when invoking with this redirection. Note that this will mask other errors with ssh; you may need to remove this for debugging purposes.
In my case, forcing pty allocation on the outer ssh of a two-level ssh invocation fixed the problem.
Details:
When you provide a command for ssh to run ( e.g. ssh some_server "do_some_command" ), then ssh assumes you won't need an interactive session, and it will not allocate a pty as it submits the "do_some_command" job you asked it to.
However, things get interesting if you have two layers of ssh (e.g. let's say you want to ssh into a "gateway" machine first, and from there you ssh into an "inner" machine and run some "inner_command").
The thing is, with a two-layer ssh'ing job, from the perspective of the outer ssh, you are requesting that the outer ssh run a non-interactive command, hence the outer ssh will not allocate a tty.
If the command you are running in the inner ssh is meant to be interactive, it will probably want to query tty attributes and it will (righteously) complain that it is not being run on a tty.
The solution in my case was to force the outer ssh to allocate a pty, by using the -t argument. So it looked like this:
ssh -t <gateway_machine> "ssh <inner_machine> \"<inner_interactive_command>\" "
Greetings to the sysadmins out there

Warning: remote port forwarding failed for listen port 52698

I'm using SSH to access my university's afs system. I like to use rmate (remote TextMate), which requires SSH tunneling, so I included this alias in my .bashrc.
alias sshr=ssh -R 52698:localhost:52698 username#corn.myschool.edu
It has always worked until now.
I had the same problem. In order to find the port that is already open, you have to issue this command on the 'corn.myschool.edu' computer:
sudo netstat -plant | grep 52698
And then kill all of the processes that come up with this (replace xxxx with the process ids)
sudo kill -9 xxxx
(UPDATED: changed the option to be -plant as it is a nice mnemonic)
I had another SSH connection open. I just needed to close that connection before I opened my SSH tunnel.
Further Explanation:
Once one ssh connection has been established, subsequent connections will produce a message:
Warning: remote port forwarding failed for listen port 52698
This message is harmless, as the forward can only be set up once and one forward will work for all ssh connections to the same machine. The original ssh session that opened the forward will stay open when you exit the shell until all remote editing sessions are finished.
I experienced this problem, but it was while connecting to a server on which I don't have sudo priviliges, so the top response suggesting runing sudo netstat ... wasn't feasible for me.
I eventually figured out it was because there were still instances of rmate running, so I used ps to list the running processes and then kill -9 pid (where pid is the process ID for rmate).
This solved my problem reported here as well. To avoid this notification "AllowTcpForwarding" should be enabled in SSH config.
In my case, the problem was that the remote system didn't have DNS properly set up, and it couldn't even resolve its own hostname. Make sure you have a working DNS in /etc/resolv.conf at the remote system.