Search code examples
pythonsshservicesystemd

Python script (which open Reverse SSH tunnel) called by service doesn't work


Here is my python script:

#!/usr/bin/env python3
import subprocess

subprocess.run(['ssh', '-fNT','-o', 'ExitOnForwardFailure=yes', '-R', '2222:localhost:22', 'martin@192.168.11.111'])

called by my service:

[Unit]
Description=reverse SSH
After=multi-user.target
Conflicts=getty@tty1.service

[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/Public/OnPushButton_PULLUP.py
User=pi
Group=pi
WorkingDirectory=/home/pi/Public/
StandardInput=tty-force

[Install]
WantedBy=multi-user.target

This script exit 0/ Success if I trust systemctl, even if ssh tunnel connection doesn't work after .

● reverse_ssh.service - reverse SSH
   Loaded: loaded (/lib/systemd/system/reverse_ssh.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Thu 2019-08-01 10:01:21 CEST; 6min ago
  Process: 549 ExecStart=/usr/bin/python3 /home/pi/Public/OnPushButton_PULLUP.py (code=exited, status=0/SUCCESS)
 Main PID: 549 (code=exited, status=0/SUCCESS)

août 01 10:01:19 raspberrypi systemd[1]: Started reverse SSH.

If I execute this script standalone (I mean like "./script.py") this script works. At the moment I use service to call it this issue occurs...Where did I do it wrong ??

Thanks !

EDIT

Problem solved. The problem was on my service file. I had to change"Type:simple" to "Type=forking" because I need to call another process from my python script. I also have to wait until device get an @IP otherwise the script script trew "Host unreacheable" For this I used this service file at the end:

[Unit]
Description=reverse SSH
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=forking
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/python3 /home/pi/Public/OnPushButton_PULLUP.py
User=pi
Group=pi
WorkingDirectory=/home/pi/Public/
TimeoutSec=infinity

[Install]
WantedBy=multi-user.target

Normally adding just this works:

Wants=network-online.target
After=network.target network-online.target

But it didn't for me. That's why I put a :

ExecStartPre=/bin/sleep 10

This line mention to the service that he will wait 10s before trying to be executed. This will give time to device to get @IP from the dhcp.


Solution

  • Finally, forking wasn't the solution. Forking was okay but with this Type of service, the script was stuck on activating until user push the button. This was a problem, other services were waiting for this service to be running, stoped or at least loaded but not stuck on activting. This issue was induced by while loop (true until the user push the button). An then once the user pushed the button the service was running or exit 0, not before. I changed the service with this following one and it worked:

    [Unit]
    After=network.target network-online.target
    Description=reverse SSH
    Wants=network-online.target
    
    [Service]
    ExecStart=/usr/bin/python3 /home/pi/OnPushButton_PULLUP.py
    ExecStartPre=/bin/sleep 10
    Group=pi
    RemainAfterExit=yes
    TimeoutSec=infinity
    Type=simple
    User=pi
    WorkingDirectory=/home/pi/
    
    [Install]
    WantedBy=multi-user.target
    

    Notice the "RemainAfterexit=Yes" otherwise the sshtunnel process(induced by this script) will be closed when the programm is exited.