tsl0922 / ttyd

Share your terminal over the web
https://tsl0922.github.io/ttyd
MIT License
8.15k stars 895 forks source link

disconnect with util-linux /bin/login command #768

Closed terefang closed 1 year ago

terefang commented 3 years ago

Describe the bug ttyd disconnects on browser connect if command is /bin/login from util-linux

To Reproduce Steps to reproduce the behavior:

ttyd.x86_64 -p 8080 /bin/login

Expected behavior ttyd should not disconnect

Environment:

Additional context

terefang commented 3 years ago

done some research:

it seams that util-linux login is sending vhangup to clean the terminal at: https://github.com/karelzak/util-linux/blob/master/login-utils/login.c#L569

on the console, login is run from (a)getty, which does not seam to mind.

terefang commented 3 years ago

ttyd log of a (bad) recurring disconnect session

root@appl:~ # /usr/sbin/ttyd -d 7 -p 8022 /usr/bin/login
[2021/09/13 08:01:29:6088] N: ttyd 1.6.3-3b174da (libwebsockets 4.1.6-)
[2021/09/13 08:01:29:6091] N: tty configuration:
[2021/09/13 08:01:29:6093] N:   start command: /usr/bin/login
[2021/09/13 08:01:29:6095] N:   close signal: SIGHUP (1)
[2021/09/13 08:01:29:6097] N:   terminal type: xterm-256color
[2021/09/13 08:01:29:6099] N: LWS: 4.1.6-, loglevel 7
[2021/09/13 08:01:29:6101] N: NET SRV H1 WS IPV6-off
[2021/09/13 08:01:29:6103] N:  Using foreign event loop...
[2021/09/13 08:01:29:6105] N:  Listening on port: 8022
[2021/09/13 08:01:46:7027] N: HTTP / - 192.168.178.5
[2021/09/13 08:01:47:0083] N: HTTP /token - 192.168.178.5
[2021/09/13 08:01:47:2965] N: WS   /ws - 192.168.178.5, clients: 1
[2021/09/13 08:01:47:3260] N: started process, pid: 757
[2021/09/13 08:01:47:3298] E: read_cb: EIO (i/o error)
[2021/09/13 08:01:47:3298] E: read_cb: EIO (i/o error)
[2021/09/13 08:01:47:3300] N: WS closed from 192.168.178.5, clients: 0
[2021/09/13 08:01:47:3301] N: killing process 757 with signal: 1 (SIGHUP)
[2021/09/13 08:01:47:3303] N: process killed with signal 1 (SIGHUP), pid: 757
[2021/09/13 08:01:47:6038] N: HTTP /token - 192.168.178.5
[2021/09/13 08:01:47:6064] N: WS   /ws - 192.168.178.5, clients: 1
[2021/09/13 08:01:47:6076] N: started process, pid: 758
[2021/09/13 08:01:47:6103] E: read_cb: EIO (i/o error)
[2021/09/13 08:01:47:6104] E: read_cb: EIO (i/o error)
[2021/09/13 08:01:47:6106] N: WS closed from 192.168.178.5, clients: 0
[2021/09/13 08:01:47:6106] N: killing process 758 with signal: 1 (SIGHUP)
[2021/09/13 08:01:47:6109] N: process killed with signal 1 (SIGHUP), pid: 758
terefang commented 3 years ago

ttyd log of a good session with manual disconnect from browser

root@appl:~ # /usr/sbin/ttyd -d 7 -p 8022 /usr/bin/busybox login
[2021/09/13 08:05:15:6555] N: ttyd 1.6.3-3b174da (libwebsockets 4.1.6-)
[2021/09/13 08:05:15:6557] N: tty configuration:
[2021/09/13 08:05:15:6560] N:   start command: /usr/bin/busybox login
[2021/09/13 08:05:15:6562] N:   close signal: SIGHUP (1)
[2021/09/13 08:05:15:6564] N:   terminal type: xterm-256color
[2021/09/13 08:05:15:6566] N: LWS: 4.1.6-, loglevel 7
[2021/09/13 08:05:15:6568] N: NET SRV H1 WS IPV6-off
[2021/09/13 08:05:15:6571] N:  Using foreign event loop...
[2021/09/13 08:05:15:6573] N:  Listening on port: 8022
[2021/09/13 08:05:24:1001] N: HTTP / - 192.168.178.5
[2021/09/13 08:05:24:3452] N: HTTP /token - 192.168.178.5
[2021/09/13 08:05:24:3750] N: WS   /ws - 192.168.178.5, clients: 1
[2021/09/13 08:05:24:3846] N: started process, pid: 778
[2021/09/13 08:05:59:7148] N: WS closed from 192.168.178.5, clients: 0
[2021/09/13 08:05:59:7148] N: killing process 778 with signal: 1 (SIGHUP)
leifliddy commented 2 years ago

@terefang Thank you such much!! I've been dealing with this issue for ages. Can't believe you found a workaround for it!! I've had to refresh the web page over and over again to get a login prompt. This is going to make my life so much easier ; )

[Unit]
Description=ttyd daemon
After=network.target nss-lookup.target

[Service]
Type=exec
ExecStart=/usr/local/bin/ttyd -P 45 -i lo busybox login 
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Everything works perfect now (it's bound to localhost as I'm reverse proxying this connection) BTW, the word you're looking for is seems not seams ; )

Good work man....

terefang commented 2 years ago

@leifliddy sorry for my bad english

under what distro/os is this working ?

i have the problem that my version of busybox is statically compiled and does not honor pam configuration

leifliddy commented 2 years ago

@terefang That was just a light-hearted comment, your English is really good, no need to apologize.

I was having issues running ttyd on Fedora for that last couple of years. Currently running it on Fedora 35

I just installed the busybox rpm and it "just worked"

[leif.liddy@cloud ~]$ rpm -qi busybox
Name        : busybox
Epoch       : 1
Version     : 1.34.1
Release     : 1.fc35
Architecture: x86_64
Install Date: Mon Dec 27 09:52:53 2021
Group       : Unspecified
Size        : 1329803
License     : GPLv2
Signature   : RSA/SHA256, Fri Oct  1 17:53:55 2021, Key ID db4639719867c58f
Source RPM  : busybox-1.34.1-1.fc35.src.rpm
Build Date  : Thu Sep 30 23:45:32 2021
Build Host  : buildhw-x86-16.iad2.fedoraproject.org
...

> I have the problem that my version of busybox is statically compiled Busybox is always compiled as a statically-linked binary, that's sort of the point.

[leif.liddy@cloud ~]$ ldd /usr/sbin/busybox
    not a dynamic executable

You've made an interesting point about it not honoring the pam configuration. Since it's statically-linked, I suppose it wouldn't honor pam at all. Actually, I'm not sure exactly sure how busybox integrates with the host system like that --I've never really thought about it. Hmmm...I can test this out on an EL8 system later this week.

It just worked on Fedora, so I never really looked into how exactly it was working.

[root@cloud ~]# busybox login
cloud.redacted.com login: leif.liddy
Password: 
[leif.liddy@cloud ~]$ 

Since there's no native busybox rpm for EL8, I'll just modify the Fedora source rpm to install on EL8 (I've done this many times before).

https://ftp.halifax.rwth-aachen.de/fedora/linux/updates/35/Everything/source/tree/Packages/b/busybox-1.34.1-1.fc35.src.rpm

From a cursory look, it doesn't appear that PAM support in enabled in the Fedora source RPM.

[root@black SOURCES]# grep PAM busybox-static.config 
# CONFIG_PAM is not set

What sort of PAM-related issues are you encountering?
Could you please provide me with some specific examples so I can replicate the issue? Maybe we could try compiling busybox with PAM support enabled and see if that works for you.
I'll have time later this week to test this out...

terefang commented 2 years ago

i have found out that compiling busybox statically with pam enabled will cause dynamic linker issues or segfaults at runtime usage (i have tried this both with glibc and musl on EL7/8 systems)

my use-case is build a sort of appliance that has a pam config setup to authenticate with pam_tacplus, pam_radius or pam_ldapd (according to the chosen configuration) and let users login via web-browser rather than having the need for a ssh client installed, like kind of a ssh-terminal-server (for dumb/locked-down windows clients).

for reference, this is the non-pam busybox config i use for compiling https://gist.github.com/terefang/c0263eba5ca329a05e24b5b03042f5d0

terefang commented 2 years ago

any updates ?

terefang commented 1 year ago

any updates ?

tsl0922 commented 1 year ago

Can't reproduce it on Ubuntu, I have no idea.

[2021/09/13 08:01:47:6103] E: read_cb: EIO (i/o error)
[2021/09/13 08:01:47:6104] E: read_cb: EIO (i/o error)

These errors indicates that ttyd can not read from pty, it should be the reason why it disconnect.

terefang commented 1 year ago

have you looked at the source of the login command in ubuntu ? which version of ubuntu ?

terefang commented 1 year ago

futher research: i traced the ubuntu sources to this:

https://salsa.debian.org/debian/util-linux/-/blob/master/login-utils/login.c#L576

has the same vhangup code, that prohibits ttyd from reading from the pty.

        /* Kill processes left on this tty */
    tcsetattr(0, TCSANOW, &ttt);

    /*
     * Let's close file descriptors before vhangup
     * https://lkml.org/lkml/2012/6/5/145
     */
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    signal(SIGHUP, SIG_IGN);    /* so vhangup() won't kill us */
    vhangup();
    signal(SIGHUP, SIG_DFL);

    /* open stdin,stdout,stderr to the tty */
    open_tty(cxt->tty_path);
terefang commented 1 year ago

after reading the comments from the lkml, i will give up.

this feature in login is actually a security fix that does not cater to the use case of ttyd.

Salamandar commented 11 months ago

I would like to revive this issue as I get the same behaviour, but not with login: with ssh. I’m using basically this : https://github.com/leshniak/httpsh/blob/master/usr/local/bin/ttyd-login and I see basically the same read_cb: EIO (i/o error) errors in the log file at times. Sometimes not.

Here’s the latest deconnection I had, after exactly a minute of inactivity:

[2023/12/05 14:58:03:2675] N: WS closed from 127.0.0.1, clients: 0
[2023/12/05 14:58:03:2678] N: killing process 2935674 with signal: 1 (SIGHUP)
[2023/12/05 14:58:03:2685] N: process killed with signal 1 (SIGHUP), pid: 2935674
[2023/12/05 14:58:04:6204] N: WS   / - 127.0.0.1, clients: 1
[2023/12/05 14:58:04:6724] N: started process, pid: 2936146

EDIT: actually it was nginx timeout. See https://github.com/tsl0922/ttyd/issues/445.