linux tty 中文shell,从弹个shell到弹个终端窗口tty

Simple: shell over socket

## netcat

# client

nc  -nvlp 13337

# server

nc -e /bin/sh localhost 13337

# tips

# RHEL系本地监听不需要指定-p参数 使用nc -lv 13337

# FreeBSD系没有-e参数,使用如下

rm -f x; mkfifo x; /bin/sh 2>&1  x

## socat

# client

socat - TCP:localhost:1337

# server

socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash

缺陷:

部分程序无法正常的退出,按CTRL+C会直接退出终端,如top,vim,emacs

Better: tty over socket

# server

socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash,pty,stderr,setsid,sigint,sane

# client

socat FILE:`tty`,raw,echo=0 TCP:localhost:1337

现在我们就有了一个 tty会话窗口, 我们可以按 Ctrl-C (^C) ,也可以运行一些tty命令如: top, vim, emacs, ssh, su, sudo等

问题:

运行部分tty程序的时候会遇到显示窗口比较小的问题,采用如下解决

# 设置本地终端

$ stty -a

speed 38400 baud; rows 40; columns 130; line = 0;

# 设置连接终端

$ stty rows 40 cols 130

缺陷:

每次执行一次窗口的会话,就需要重新设置一次

Implementing it

Since there is no option in socat to magically do that, first we need to re-implement both server and client sides of what socat was doing, then we will improve it.

server: we need to get a pseudo-terminal, which is OS-specific. On Linux we'll open /dev/ptmx, this gives us the master which we'll connect to the socket. With an ioctl we get the name of the slave and open its corresponding /dev/pts/N (like your terminal!), unlock it and give it as stdin/stdout/stderr to the shell.

client: we need to take over the terminal, the shell's stdin being a terminal we'll make it raw, then connect it to the socket. Making the terminal raw has the effect that signals such as Ctrl-C will now go on the socket.

Terminal window resizing

So we've reached the same point as we had with socat. Now, what's up with window changes? Well, turns out when you resize your terminal window a SIGWINCH signal is delivered!

Also, we can get and set the window size with ioctl TIOCGWINSZ and TIOCSWINSZ.

Here's what we can do: catch this signal on the client, get the new window size, send it over the socket to the server, which will set the window size on the pseudo-terminal, and send the same signal to the shell so it knows it can resize.

Unfortunately there's one problem: we have only one socket, and it already relays the terminal data. So we need another, or rather, we can multiplex the socket to give us 2 channels: one to exchange data, one to push window size information from client to server.

We do that and finally... we have it ! A remote shell terminal, which we can resize and it gets updated. Fancy! I did an implementation in Go if you want to look or try.

Now if we just add some TLS, we're not too far from SSH. And using this multiplex of streams on the socket we could even add port forwarding, file transfer, etc. all in the same connection.

final:

作者提供了一个自己用GO实现的服务端和客户端。

PS: 上面太长了,不翻译了 - -

Via: http://blog.stalkr.net/2015/12/from-remote-shell-to-remote-terminal.html

2016-5-23:

python -c 'import pty; pty.spawn("/bin/bash")'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值