Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Perl terminal access to linux server

by Polyglot (Chaplain)
on Sep 22, 2021 at 07:46 UTC ( [id://11136943]=perlquestion: print w/replies, xml ) Need Help??

Polyglot has asked for the wisdom of the Perl Monks concerning the following question:

Can Perl provide a direct link to terminal access on a linux webserver, and/or is there a module that would provide the tools for this in similar style to the DBI modules that give direct access to databases?

Assume that the script were setuid root, so permissions were not an issue.

I'm aware of the use of backticks, etc. to execute commands within a script, but am wondering if there is a more interactive approach instead of using only pre-scripted commands.

For the purposes of this question, I'm interested in what is possible more than what might be considered standard practice and/or secure. However, feel free to wax eloquent on the security risks of letting someone use setuid scripts on the server.

Blessings,

~Polyglot~

Replies are listed 'Best First'.
Re: Perl terminal access to linux server
by Corion (Patriarch) on Sep 22, 2021 at 08:12 UTC

    Depending on how interactive you want things to be, Net::SSH2 and/or Net::SSH::Any allow you to run anything from a script.

    As a general approach, why use a suid script when you can configure special SSH keys together with a premade command so that you can trigger a specific command directly as root? See the authorized_keys manpage on the command= entry.

      Thank you for the helpful response. I do appreciate it. Reading the man page you linked, however, I am struggling to understand it--maybe it's above my level.

      How exactly is the Net::SSH2 protocol qualitatively different from an ordinary remote login via SSH? I'm not interested in passing things through Perl just for the sake of it, but rather to have a different interface and/or useraccess option.

      Okay, I'll give an example to help illustrate the motivation for the question.

      Occasionally, something seems to glitch and/or hangup on the server end with respect to the SSH daemon. When this happens, the server is still running fine, but SSH logins will not complete. The virtual server (VM) sometimes needs to be restarted in order to reopen access to the server. But if a Perl script could give some form of non-SSH-dependent access to commands on the server, the SSH daemon could be restarted without a VM reboot.

      I once, years ago, had a script that I tweaked to provide basic access to tools like ls, chmod, pico, etc. to have some basic server access in the event of a problem with the SSH entry. Unfortunately, the SSH issues ended up being more than could be handled by my minimal Perl-script functionality. That's the sort of functionality I'm contemplating once again.

      Blessings,

      ~Polyglot~

        Oh - sorry, then I completely misunderstood your answer. I thought you wanted to do it the other way around, automating things through ssh , but you want to issue commands through a secondary way.

        I would first look at where the problem stems from and whether running a second sshd on a different port allows you to do the management through that one. If the server is unresponsive due to network/io/ram congestion, that won't help you though.

        Complete tangent to your original request, but I solved a similar problem by running dropbear sshd on a different port, with dropbear configured not to use PAM and pointed at a special /etc/passwd file that only lists the root user and with password logins disabled, so that the only way to use this ssh daemon is by connecting with a known private key. I use a locally-encrypted private key. Also the root user’s shell of this login is set to busybox’s sh, so none of the bash profile stuff runs and most shell commands run as builtins. Then, I set the oom priority of the dropbear sshd to the lowest possible value and give it high io and cpu scheduling priority.

        This creates a really secure and resilient second method to access the server. It allows me to log in in the middle of a forkbomb, or log in after OOM killer trashed everything, and even sometimes log in when the root volume is dead and everything that touches disk gets permanently paused.

        also a tangent: this idea was mentioned once at the cb, not sure by whom: add something to the cron of the remote host (the one whose sshd sometimes needs to be restarted) which will regularly check the sshd and if needs to be restarted, or simply restarting the sshd when nobody connected (do a who). Or even reboot the system (with all the caveats for current sessions).

Re: Perl terminal access to linux server
by soonix (Canon) on Sep 22, 2021 at 09:38 UTC
    By "terminal access", I assume you mean a commandline interface via SSH or Telnet (or Serial connection), so Control::CLI comes to my mind.

    On the machine from where you open the connection, "setuid root" doesn't help you, because the Linux webserver you're connecting to usually would have its own authorization checks. If something running on the Linux webserver - well, that's another can of worms… see e.g. OWASP Secure Coding Practices (this seems currently being migrated, archived here)

Re: Perl terminal access to linux server
by afoken (Chancellor) on Sep 22, 2021 at 10:45 UTC
    Can Perl provide a direct link to terminal access on a linux webserver,

    "Terminal access" as in connecting a VT100 to an RS232 connection on the Linux machine?

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Sorry if my intent was unclear. By "terminal access" I mean "command prompt" of the sort usually accessed by some form of shell terminal, e.g. bash, csh, etc. I have no need for, nor interest in, going back to the days of modems. I just want to execute privileged commands on the server.

      Blessings,

      ~Polyglot~

        By "terminal access" I mean "command prompt" of the sort usually accessed by some form of shell terminal, e.g. bash, csh, etc.

        Some ways to get a command prompt on a Linux machine:

        • Virtual terminal a.k.a. console, i.e. keyboard and monitor connected to the machine. Linux emulates one or more VT100 derivates, and you can use keyboard shortcuts (typically Alt plus one of the F-keys) to switch between the terminals.
        • Real terminal, e.g. the original VT100, or just about any other computer running a terminal emulator, connected to one of the serial ports of the Linux machine. On an x86-derived PC, typically not enabled by default. Other hardware, especially servers and embedded hardware, may use a serial port for the console.
        • Terminal emulator (xterm and friends) displayed on an X11 or Wayland server ("Graphics mode"). Typically not available on servers.
        • Telnet via any TCP/IP connection. Not encrypted, password transmitted as plain text, insecure and thus typically not enabled by default.
        • Remote shell via any TCP/IP connection. Not encrypted, password often transmitted as plain text, insecure and thus typically not enabled by default.
        • SSH via any TCP/IP connection. Encrypted, secure with recent encryption protocols, can use public keys instead of passwords.
        • Remote code execution exploits in existing server implementations. Rarely legal, not always reliable, and often not encrypted.
        I just want to execute privileged commands on the server.

        You don't necessarily need a command prompt for that. Most privileged commands on Linux can run fine without a command prompt.

        To execute unprivileged commands, just use fork, exec, and wait, or one of the wrappers (qx, system, ``, pipe open, ...). That's not even specific for Perl, almost all languages running on Linux can start other processes.

        And to run privileged commands, just use sudo. Yes, sudo needs to be configured, and the documentaton for its config file was probably the inspiration for the right-hand side of https://xkcd.com/1343/, but it allows a very precise control about who is given privileged access, to which programs, and even the parameters passed to the programs can be restricted. Running sudo is trivial. Just execute sudo instead of the privileged command, and pass the privileged command and all of its parameters as parameters to sudo.

        When running CGIs or SSI from Apache, you can alternatively use suEXEC. suEXEC is sufficiently paranoid, but not as flexible as sudo. And it explicitly prevents running code as root.

        <Update>Just for inspiration: Webmin routinely runs privileged commands from a webserver. Unfortunately, it does so by simply NOT dropping privileges when starting the webserver, so everything runs as root. See Building a web-based system administration interface in Perl and especially Re: Building a web-based system administration interface in Perl for a better way; and Best way to write to a file owned by root? for some paranoid file handling when running with elevated privileges.</Update>

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        I think your intention is still not clear.

        Could you describe in detail the interaction you expect from the user accessing that web site?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11136943]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-03-28 08:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found