Merge pull request #710 from skuhl/tproxy-check-root

Improve error message if tproxy method is used without running as root.
This commit is contained in:
Brian May 2022-01-06 10:26:27 +11:00 committed by GitHub
commit b00f2e0a68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ from sshuttle.methods import BaseMethod
from sshuttle.helpers import debug1, debug2, debug3, Fatal, which from sshuttle.helpers import debug1, debug2, debug3, Fatal, which
import socket import socket
import os
IP_TRANSPARENT = 19 IP_TRANSPARENT = 19
@ -69,6 +70,15 @@ class Method(BaseMethod):
return None return None
return srcip, dstip, data return srcip, dstip, data
def setsockopt_error(self, e):
"""The tproxy method needs root permissions to successfully
set the IP_TRANSPARENT option on sockets. This method is
called when we receive a PermissionError when trying to do
so."""
raise Fatal("Insufficient permissions for tproxy method.\n"
"Your effective UID is %d, not 0. Try rerunning as root.\n"
% os.geteuid())
def send_udp(self, sock, srcip, dstip, data): def send_udp(self, sock, srcip, dstip, data):
if not srcip: if not srcip:
debug1( debug1(
@ -77,16 +87,26 @@ class Method(BaseMethod):
return return
sender = socket.socket(sock.family, socket.SOCK_DGRAM) sender = socket.socket(sock.family, socket.SOCK_DGRAM)
sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sender.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1) try:
sender.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
except PermissionError as e:
self.setsockopt_error(e)
sender.bind(srcip) sender.bind(srcip)
sender.sendto(data, dstip) sender.sendto(data, dstip)
sender.close() sender.close()
def setup_tcp_listener(self, tcp_listener): def setup_tcp_listener(self, tcp_listener):
tcp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1) try:
tcp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
except PermissionError as e:
self.setsockopt_error(e)
def setup_udp_listener(self, udp_listener): def setup_udp_listener(self, udp_listener):
udp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1) try:
udp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
except PermissionError as e:
self.setsockopt_error(e)
if udp_listener.v4 is not None: if udp_listener.v4 is not None:
udp_listener.v4.setsockopt( udp_listener.v4.setsockopt(
socket.SOL_IP, IP_RECVORIGDSTADDR, 1) socket.SOL_IP, IP_RECVORIGDSTADDR, 1)