Category Archives: computers

Unix/Linux safe remote commands

Do you need to execute some commands from batch scripts on a remote host but don’t want to allow full shell access? For a single command, you can use sshd’s ForceCommand, but it allows only one command per account. This text explains how you can execute safe, remote, limited multiple commands.

The trick :

  • Create a special, unique, passwordless user for remote commands, such as “sudo_lover”.
  • ForceCommand‘ runs a Python script named “use_sudo,” which acts like a safe version of “sudo $SSH_ORIGINAL_COMMAND”. You can configure allowed commands with sudo.
  • use_sudo‘ logs commands (auth.log), making it easy to add a command by almost a copy and paste (for example, configuring rsync without the log would be almost impossible).

One drawback is the difficulty in redirecting STDOUT/STDERR. To redirect STDOUT, I use a second program named “out_to,” which takes the file to redirect to and the command to execute.

cat use_sudo
#!/usr/bin/python3
import os
import shlex
import logging
import logging.handlers
from logging.handlers import SysLogHandler

# logger configuration : auth.info
syslogHandler = logging.handlers.SysLogHandler(address='/dev/log', facility="auth")
formatter = logging.Formatter('use_sudo: %(levelname)s - %(message)s')
syslogHandler.setFormatter(formatter)

logger = logging.getLogger('use_sudo')
logger.setLevel(logging.INFO)
logger.addHandler(syslogHandler)

command_from_env = os.environ.get("SSH_ORIGINAL_COMMAND")
if(not command_from_env):
    print("SSH_ORIGINAL_COMMAND is undefined.")
    exit(1)
command_with_arguments = shlex.split(command_from_env)
logger.info(str(command_with_arguments))

command_for_sudo = [f"/usr/bin/sudo -n {command_with_arguments[0]} ...",'-n'] + command_with_arguments
os.execv("/usr/bin/sudo", command_for_sudo)

cat out_to
#!/usr/bin/python3
import os
import sys
import subprocess

arguments = sys.argv
outfile=arguments[1]
command = arguments[2:]
with open(outfile, 'w') as outfile_h:
    try:
        subprocess.run(command, stdin=sys.stdin, stdout=outfile_h, stderr=sys.stderr, check=True)
    except subprocess.CalledProcessError as e:
        print(f"Error while executing : {e}")

How to route specific traffic through a VPN on Linux with nftables

Introduction

Here I explain a strong solution to route traffic to a VPN using the group of the processes. We discuss security at the end. After the configuration, if you want to run ktorrent using the VPN you just have to run sudo -g vpn_euro ktorrent. You will be able to use serveral VPN and no VPN the same time, per process.

Continue reading How to route specific traffic through a VPN on Linux with nftables