Using Sshuttle as a service

1 — Service Account

On the server initiating sshuttle (client), create a dedicated Sshuttle service account and create an SSH folder

root@client> 
groupadd sshuttle
useradd -d /home/sshuttle -g sshuttle sshuttle
mkdir /home/sshuttle/.ssh
chown -R sshuttle:sshuttle /home/sshuttle
chmod 700 /home/sshuttle/.ssh
root@client> 
ssh-keygen -o -a 100 -t ed25519 -N "" -C "sshuttle_key" -f /home/sshuttle/.ssh/id_ed25519
root@client> su sshuttle
sshuttle@client> ssh targetServer

2 — Sudo access

Sshuttle client needs sudo access to modify your firewall (on client only, not on the target server)


sshuttle ALL=(root) NOPASSWD: /usr/bin/python /usr/share/sshuttle/main.py /usr/bin/python --firewall 12*** 0

3 — Install package

install Sshuttle on your client server

root@client> yum install sshuttle

4 — Service scripts

add 2 service scripts,

root@client> vi /etc/systemd/system/sshuttle.service[Unit]
Description=sshuttle service
After=network.target
[Service]
User=sshuttle
Restart=always
Type=forking
WorkingDirectory=/etc/sshuttle
ExecStart=/etc/sshuttle/sshuttle.py start
ExecStop=/etc/sshuttle/sshuttle.py stop
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
mkdir /etc/sshuttle
chown sshuttle:sshuttle /etc/sshuttle
sshuttle@client>  vi /etc/sshuttle/sshuttle.py
# make script executable
chmod +x /etc/sshuttle/sshuttle.py
systemctl status sshuttle
systemctl start sshutle
systemctl stop sshuttle

5 — Config File

finally, you add a config file to tell sshuttle where you want to connect to and what networks you want to route via the target hop server, you can add multiple hop servers and multiple networks that you want to route via these hop proxies,

sshuttle@client> vi /etc/sshuttle/config.json{
"HopServerA": [
"12.182.293.180/32",
"129.33.78.18/32",
"129.13.280.0/24",
"sftp.somehost.com"
],
"HopServerB": [
"11.38.26.0/24"
]
}
systemctl restart sshuttle
cat /srv/salt/pillar/servers/nycweb01.slssshuttle:
HopServerA:
- 12.182.293.180/32 # customer A
- 129.33.78.18/32 # customer B
- 129.13.280.0/24 # customer C
- sftp.somehost.com # ftp customer D
HopServerB:
- 11.38.26.0/24 # customer F

Update #1 — Keep Alive

I also updated this part of the sshuttle.py script, with some additional settings (based on my work performance testing)

rpath = "-r {0}@{1} {2} -l listen '0.0.0.0' --ssh-cmd 'ssh -o ServerAliveInterval=60' --no-latency-control".format(ssh_user, rhost, netrange)
--ssh-cmd 'ssh -o ServerAliveInterval=60' --no-latency-control'

Update #2 — Proxying via 2 or more hops

if you need to use sshuttle to hop over 2 or more hops to get to a destination, for example

A needs to get to D, via B and C
# config.json on server A{
"0:serverB": [
"serverC hostname or IP",
],
"1:serverC": [
"serverD hostname or IP"
]
}
# config.json on server B
{
"serverC": [
"serverD hostname or IP"
]
}
sleep 3 to establish an SSH handshake
rpath = "-r {0}@{1} {2} -l {{ salt['pillar.get']('sshuttle:listen', '127.0.0.1') }} --ssh-cmd 'ssh -o ServerAliveInterval=60' --no-latency-control".format(ssh_user, rhost, netrange)
## Server B pillar
sshuttle:
listen: 0.0.0.0
relays:
serverC:
- serverD ip or hostname
rpath = "-r {0}@{1} {2} -l 0.0.0.0 --no-latency-control".format(ssh_user, rhost, netrange)
#3 connection will only start after #1 is established

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store