SSH – Force Command execution on login even withou

2019-03-09 21:54发布

I am creating a restricted user without shell for port forwarding only and I need to execute a script on login via pubkey, even if the user is connected via ssh -N user@host which doesn't asks SSH server for a shell.

The script should warn admin on connections authenticated with pubkey, so the user connecting shouldn't be able to skip the execution of the script (e.g., by connecting with ssh -N).

I have tried to no avail:

  • Setting the command at /etc/ssh/sshrc.
  • Using command="COMMAND" in .ssh/authorized_keys (man authorized_keys)
  • Setting up a script with the command as user's shell. (chsh -s /sbin/myscript.sh USERNAME)
  • Matching user in /etc/ssh/sshd_config like: Match User MYUSERNAME ForceCommand "/sbin/myscript.sh"

All work when user asks for shell, but if logged only for port forwarding and no shell (ssh -N) it doesn't work.

标签: ssh sshd
3条回答
叛逆
2楼-- · 2019-03-09 22:23

The ForceCommand option runs without a PTY unless the client requests one. As a result, you don't actually have a shell to execute scripts the way you might expect. In addition, the OpenSSH SSHD_CONFIG(5) man page clearly says:

The command is invoked by using the user's login shell with the -c option.

That means that if you've disabled the user's login shell, or set it to something like /bin/false, then ForceCommand can't work. Assuming that:

  1. the user has a sensible shell defined,
  2. that your target script is executable, and
  3. that your script has an appropriate shebang line

then the following should work in your global sshd_config file once properly modified with the proper username and fully-qualified pathname to your custom script:

Match User foo
    ForceCommand /path/to/script.sh
查看更多
混吃等死
3楼-- · 2019-03-09 22:31

I am the author of the OP. Also, you can implement a simple logwatcher as the following written in python3, which keeps reading for a file and executes a command when line contains pattern.

logwatcher.python3

#!/usr/bin/env python3

# follow.py
#
# Follow a file like tail -f.

import sys
import os
import time

def follow(thefile):
    thefile.seek(0,2)
    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.5)
            continue
        yield line

if __name__ == '__main__':
    logfilename = sys.argv[1]
    pattern_string = sys.argv[2]
    command_to_execute = sys.argv[3]

    print("Log filename is: {}".format(logfilename))

    logfile = open(logfilename, "r")
    loglines = follow(logfile)

    for line in loglines:
        if pattern_string in line:
            os.system(command_to_execute)

Usage

  1. Make the above script executable:

chmod +x logwatcher.python3

  1. Add a cronjob to start it after reboot

crontab -e

Then write this line there and save it after this:

@reboot /home/YOURUSERNAME/logwatcher.python3 "/var/log/auth.log" "session opened for user" "/sbin/myscript.sh"

The first argument of this script is the log file to watch, and the second argument is the string for which to look in it. The third argument is the script to execute when the line is found in file.

It is best if you use something more reliable to start/restart the script in case it crashes.

查看更多
手持菜刀,她持情操
4楼-- · 2019-03-09 22:41

I am the author of the OP; I came to the conclusion that what I need to achieve is not possible using SSH only to the date (OpenSSH_6.9p1 Ubuntu-2, OpenSSL 1.0.2d 9 Jul 2015), but I found a great piece of software that uses encrypted SPAuthentication to open SSH port and it's new version (to the date of this post, it's GitHub master branch) has a feature to execute a command always that a user authorizates successfully.

FWKNOP - Encrypted Single Packet Authorization

FWKNOP set iptables rules that allow access to given ports upon a single packet encrypted which is sent via UDP. Then after authorization it allow access for the authorized user for a given time, for example 30 seconds, closing the port after this, leaving the connection open.

1. To install on an Ubuntu linux:

The current version (2.6.0-2.1build1) on Ubuntu repositories to the date still doesn't allow command execution on successful SPA; (please use 2.6.8 from GitHub instead)

On client machine:

sudo apt-get install fwknop-client

On server side:

sudo apt-get install fwknop-server

Here is a tutorial on how to setup the client and server machines https://help.ubuntu.com/community/SinglePacketAuthorization

Then, after it is set up, on server side:

  1. Edit /etc/default/fwknop-server
  2. Change the line START_DAEMON="no" to START_DAEMON="yes"
  3. Then run:

    sudo service fwknop-server stop

    sudo service fwknop-server start

2. Warning admin on successful SPA (email, pushover script etc)

So, as stated above the current version present in Ubuntu repositories (2.6.0-2.1build1) cannot execute command on successful SPA. If you need this feature as of the OP, but it will be released at fwknop version (2.6.8), as can it is stated here:

https://github.com/mrash/fwknop/issues/172

So if you need to use it right now you can build from github branch master which have the CMD_CYCLE_OPEN option.

3. More resources on fwknop

https://help.ubuntu.com/community/SinglePacketAuthorization

https://github.com/mrash/fwknop/ (project on GitHub)

http://www.cipherdyne.org/fwknop/ (project site)

https://www.digitalocean.com/community/tutorials/how-to-use-fwknop-to-enable-single-packet-authentication-on-ubuntu-12-04 (tutorial on DO's community)

查看更多
登录 后发表回答