mirror of
https://github.com/sshuttle/sshuttle.git
synced 2024-11-25 09:23:48 +01:00
Auto sudoers file (#269)
* added sudoers options to command line arguments * added sudoers options to command line arguments * template for sudoers file * Added option for GUI sudo * added support for GUI sudo * script for auto adding sudo file * sudoers auto add works and validates * small change * Clean up for CI * removed code that belongs in another PR * added path for package bins * added sudoers bin * added sudoers-add to setup file * fixed issue with sudoers bash script * auto sudoers now works * added --sudoers-no-modify option * bin now works with ./run * removed debug print * Updated sudoers-add script * Fixed error passing sudoers config to script * more dynamic building of sudoers file * added option to specify sudoers.d file name * fixed indent issue * fixed indent issue * indent issue * clean up * formating * docs * fix for flags * Update usage.rst * removed shell=true * cleared CI errors * cleared CI errors * removed random * cleared linter issue * cleared linter issue * cleared linter issue * updated sudoers-add script * safer temp file * moved bin directory * moved bin directory * removed print * fixed spacing issue * sudoers commands must only containe upper case latters
This commit is contained in:
parent
6ad4473c87
commit
69d3f7dc64
76
bin/sudoers-add
Executable file
76
bin/sudoers-add
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# William Mantly <wmantly@gmail.com>
|
||||||
|
# MIT License
|
||||||
|
# https://github.com/wmantly/sudoers-add
|
||||||
|
|
||||||
|
NEWLINE=$'\n'
|
||||||
|
CONTENT=""
|
||||||
|
ME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"
|
||||||
|
|
||||||
|
if [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
|
||||||
|
echo "Usage: $ME [file_path] [sudoers-file-name]"
|
||||||
|
echo "Usage: [content] | $ME sudoers-file-name"
|
||||||
|
echo "This will take a sudoers config validate it and add it to /etc/sudoers.d/{sudoers-file-name}"
|
||||||
|
echo "The config can come from a file, first usage example or piped in second example."
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" == "" ]; then
|
||||||
|
(>&2 echo "This command take at lest one argument. See $ME --help")
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$2" == "" ]; then
|
||||||
|
FILE_NAME=$1
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
FILE_NAME=$2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read -r line
|
||||||
|
do
|
||||||
|
CONTENT+="${line}${NEWLINE}"
|
||||||
|
done < "${1:-/dev/stdin}"
|
||||||
|
|
||||||
|
if [ "$CONTENT" == "" ]; then
|
||||||
|
(>&2 echo "No config content specified. See $ME --help")
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$FILE_NAME" == "" ]; then
|
||||||
|
(>&2 echo "No sudoers file name specified. See $ME --help")
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make a temp file to hold the sudoers config
|
||||||
|
umask 077
|
||||||
|
TEMP_FILE=$(mktemp)
|
||||||
|
echo "$CONTENT" > "$TEMP_FILE"
|
||||||
|
|
||||||
|
# Make sure the content is valid
|
||||||
|
visudo_STDOUT=$(visudo -c -f "$TEMP_FILE" 2>&1)
|
||||||
|
visudo_code=$?
|
||||||
|
# The temp file is no longer needed
|
||||||
|
rm "$TEMP_FILE"
|
||||||
|
|
||||||
|
if [ $visudo_code -eq 0 ]; then
|
||||||
|
echo "$CONTENT" > "/etc/sudoers.d/$FILE_NAME"
|
||||||
|
chmod 0440 "/etc/sudoers.d/$FILE_NAME"
|
||||||
|
echo "The sudoers file /etc/sudoers.d/$FILE_NAME has been successfully created!"
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Invalid sudoers config!"
|
||||||
|
echo "$visudo_STDOUT"
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
@ -5,8 +5,18 @@ Installation
|
|||||||
|
|
||||||
pip install sshuttle
|
pip install sshuttle
|
||||||
|
|
||||||
|
- Debain package manager::
|
||||||
|
sudo apt install sshuttle
|
||||||
|
|
||||||
- Clone::
|
- Clone::
|
||||||
|
|
||||||
git clone https://github.com/sshuttle/sshuttle.git
|
git clone https://github.com/sshuttle/sshuttle.git
|
||||||
cd sshuttle
|
cd sshuttle
|
||||||
./setup.py install
|
./setup.py install
|
||||||
|
|
||||||
|
|
||||||
|
Optionally after installation
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
- Add to sudoers file
|
||||||
|
sshuttle --sudoers
|
||||||
|
@ -234,6 +234,29 @@ Options
|
|||||||
makes it a lot easier to debug and test the :option:`--auto-hosts`
|
makes it a lot easier to debug and test the :option:`--auto-hosts`
|
||||||
feature.
|
feature.
|
||||||
|
|
||||||
|
.. option:: --sudoers
|
||||||
|
|
||||||
|
sshuttle will auto generate the proper sudoers.d config file and add it.
|
||||||
|
Once this is completed, sshuttle will exit and tell the user if
|
||||||
|
it succeed or not. Do not call this options with sudo, it may generate a
|
||||||
|
incorrect config file.
|
||||||
|
|
||||||
|
.. option:: --sudoers-no-modify
|
||||||
|
|
||||||
|
sshuttle will auto generate the proper sudoers.d config and print it to
|
||||||
|
stdout. The option will not modify the system at all.
|
||||||
|
|
||||||
|
.. option:: --sudoers-user
|
||||||
|
|
||||||
|
Set the user name or group with %group_name for passwordless operation.
|
||||||
|
Default is the current user.set ALL for all users. Only works with
|
||||||
|
--sudoers or --sudoers-no-modify option.
|
||||||
|
|
||||||
|
--option:: --sudoers-filename
|
||||||
|
|
||||||
|
Set the file name for the sudoers.d file to be added. Default is
|
||||||
|
"sshuttle_auto". Only works with --sudoers.
|
||||||
|
|
||||||
.. option:: --version
|
.. option:: --version
|
||||||
|
|
||||||
Print program version.
|
Print program version.
|
||||||
|
@ -60,3 +60,46 @@ the data back and forth through ssh.
|
|||||||
Fun, right? A poor man's instant VPN, and you don't even have to have
|
Fun, right? A poor man's instant VPN, and you don't even have to have
|
||||||
admin access on the server.
|
admin access on the server.
|
||||||
|
|
||||||
|
Sudoers File
|
||||||
|
------------
|
||||||
|
sshuttle can auto-generate the proper sudoers.d file using the current user
|
||||||
|
for Linux and OSX. Doing this will allow sshuttle to run without asking for
|
||||||
|
the local sudo password and to give users who do not have sudo access
|
||||||
|
ability to run sshuttle.
|
||||||
|
|
||||||
|
sshuttle --sudoers
|
||||||
|
|
||||||
|
DO NOT run this command with sudo, it will ask for your sudo password when
|
||||||
|
it is needed.
|
||||||
|
|
||||||
|
A costume user or group can be set with the :
|
||||||
|
option:`sshuttle --sudoers --sudoers-username {user_descriptor}` option. Valid
|
||||||
|
values for this vary based on how your system is configured. Values such as
|
||||||
|
usernames, groups pre-pended with `%` and sudoers user aliases will work. See
|
||||||
|
the sudoers manual for more information on valid user specif actions.
|
||||||
|
The options must be used with `--sudoers`
|
||||||
|
|
||||||
|
sshuttle --sudoers --sudoers-user mike
|
||||||
|
sshuttle --sudoers --sudoers-user %sudo
|
||||||
|
|
||||||
|
The name of the file to be added to sudoers.d can be configured as well. This
|
||||||
|
is mostly not necessary but can be useful for giving more than one user
|
||||||
|
access to sshuttle. The default is `sshuttle_auto`
|
||||||
|
|
||||||
|
sshuttle --sudoer --sudoers-filename sshuttle_auto_mike
|
||||||
|
sshuttle --sudoer --sudoers-filename sshuttle_auto_tommy
|
||||||
|
|
||||||
|
You can also see what configuration will be added to your system without
|
||||||
|
modifying anything. This can be helpfull is the auto feature does not work, or
|
||||||
|
you want more control. This option also works with `--sudoers-username`.
|
||||||
|
`--sudoers-filename` has no effect with this option.
|
||||||
|
|
||||||
|
sshuttle --sudoers-no-modify
|
||||||
|
|
||||||
|
This will simply sprint the generated configuration to STDOUT. Example
|
||||||
|
|
||||||
|
08:40 PM william$ sshuttle --sudoers-no-modify
|
||||||
|
|
||||||
|
Cmnd_Alias SSHUTTLE304 = /usr/bin/env PYTHONPATH=/usr/local/lib/python2.7/dist-packages/sshuttle-0.78.5.dev30+gba5e6b5.d20180909-py2.7.egg /usr/bin/python /usr/local/bin/sshuttle --method auto --firewall
|
||||||
|
|
||||||
|
william ALL=NOPASSWD: SSHUTTLE304
|
||||||
|
1
run
1
run
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
set -e
|
set -e
|
||||||
export PYTHONPATH="$(dirname $0):$PYTHONPATH"
|
export PYTHONPATH="$(dirname $0):$PYTHONPATH"
|
||||||
|
export PATH="$(dirname $0)/bin:$PATH"
|
||||||
|
|
||||||
python_best_version() {
|
python_best_version() {
|
||||||
if [ -x "$(command -v python3)" ] &&
|
if [ -x "$(command -v python3)" ] &&
|
||||||
|
1
setup.py
1
setup.py
@ -52,6 +52,7 @@ setup(
|
|||||||
"Programming Language :: Python :: 3.5",
|
"Programming Language :: Python :: 3.5",
|
||||||
"Topic :: System :: Networking",
|
"Topic :: System :: Networking",
|
||||||
],
|
],
|
||||||
|
scripts=['bin/sudoers-add'],
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'sshuttle = sshuttle.cmdline:main',
|
'sshuttle = sshuttle.cmdline:main',
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
import platform
|
||||||
import sshuttle.helpers as helpers
|
import sshuttle.helpers as helpers
|
||||||
import sshuttle.client as client
|
import sshuttle.client as client
|
||||||
import sshuttle.firewall as firewall
|
import sshuttle.firewall as firewall
|
||||||
@ -7,11 +8,27 @@ import sshuttle.hostwatch as hostwatch
|
|||||||
import sshuttle.ssyslog as ssyslog
|
import sshuttle.ssyslog as ssyslog
|
||||||
from sshuttle.options import parser, parse_ipport
|
from sshuttle.options import parser, parse_ipport
|
||||||
from sshuttle.helpers import family_ip_tuple, log, Fatal
|
from sshuttle.helpers import family_ip_tuple, log, Fatal
|
||||||
|
from sshuttle.sudoers import sudoers
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
opt = parser.parse_args()
|
opt = parser.parse_args()
|
||||||
|
|
||||||
|
if opt.sudoers or opt.sudoers_no_modify:
|
||||||
|
if platform.platform().startswith('OpenBSD'):
|
||||||
|
log('Automatic sudoers does not work on BSD')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
if not opt.sudoers_filename:
|
||||||
|
log('--sudoers-file must be set or omited.')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
sudoers(
|
||||||
|
user_name=opt.sudoers_user,
|
||||||
|
no_modify=opt.sudoers_no_modify,
|
||||||
|
file_name=opt.sudoers_filename
|
||||||
|
)
|
||||||
|
|
||||||
if opt.daemon:
|
if opt.daemon:
|
||||||
opt.syslog = 1
|
opt.syslog = 1
|
||||||
if opt.wrap:
|
if opt.wrap:
|
||||||
|
@ -321,6 +321,37 @@ parser.add_argument(
|
|||||||
(internal use only)
|
(internal use only)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--sudoers",
|
||||||
|
action="store_true",
|
||||||
|
help="""
|
||||||
|
Add sshuttle to the sudoers for this user
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--sudoers-no-modify",
|
||||||
|
action="store_true",
|
||||||
|
help="""
|
||||||
|
Prints the sudoers config to STDOUT and DOES NOT modify anything.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--sudoers-user",
|
||||||
|
default="",
|
||||||
|
help="""
|
||||||
|
Set the user name or group with %%group_name for passwordless operation.
|
||||||
|
Default is the current user.set ALL for all users. Only works with
|
||||||
|
--sudoers or --sudoers-no-modify option.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--sudoers-filename",
|
||||||
|
default="sshuttle_auto",
|
||||||
|
help="""
|
||||||
|
Set the file name for the sudoers.d file to be added. Default is
|
||||||
|
"sshuttle_auto". Only works with --sudoers or --sudoers-no-modify option.
|
||||||
|
"""
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--no-sudo-pythonpath",
|
"--no-sudo-pythonpath",
|
||||||
action="store_false",
|
action="store_false",
|
||||||
|
64
sshuttle/sudoers.py
Normal file
64
sshuttle/sudoers.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import getpass
|
||||||
|
from uuid import uuid4
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
from sshuttle.helpers import log, debug1
|
||||||
|
from distutils import spawn
|
||||||
|
|
||||||
|
path_to_sshuttle = sys.argv[0]
|
||||||
|
path_to_dist_packages = os.path.dirname(os.path.abspath(__file__))[:-9]
|
||||||
|
|
||||||
|
# randomize command alias to avoid collisions
|
||||||
|
command_alias = 'SSHUTTLE%(num)s' % {'num': uuid4().hex[-3:].upper()}
|
||||||
|
|
||||||
|
# Template for the sudoers file
|
||||||
|
template = '''
|
||||||
|
Cmnd_Alias %(ca)s = /usr/bin/env PYTHONPATH=%(dist_packages)s %(py)s %(path)s *
|
||||||
|
|
||||||
|
%(user_name)s ALL=NOPASSWD: %(ca)s
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def build_config(user_name):
|
||||||
|
content = template % {
|
||||||
|
'ca': command_alias,
|
||||||
|
'dist_packages': path_to_dist_packages,
|
||||||
|
'py': sys.executable,
|
||||||
|
'path': path_to_sshuttle,
|
||||||
|
'user_name': user_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def save_config(content, file_name):
|
||||||
|
process = Popen([
|
||||||
|
'/usr/bin/sudo',
|
||||||
|
spawn.find_executable('sudoers-add'),
|
||||||
|
file_name,
|
||||||
|
], stdout=PIPE, stdin=PIPE)
|
||||||
|
|
||||||
|
process.stdin.write(content.encode())
|
||||||
|
|
||||||
|
streamdata = process.communicate()[0]
|
||||||
|
returncode = process.returncode
|
||||||
|
|
||||||
|
if returncode:
|
||||||
|
log('Failed updating sudoers file.\n')
|
||||||
|
debug1(streamdata)
|
||||||
|
exit(returncode)
|
||||||
|
else:
|
||||||
|
log('Success, sudoers file update.\n')
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def sudoers(user_name=None, no_modify=None, file_name=None):
|
||||||
|
user_name = user_name or getpass.getuser()
|
||||||
|
content = build_config(user_name)
|
||||||
|
|
||||||
|
if no_modify:
|
||||||
|
sys.stdout.write(content)
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
save_config(content, file_name)
|
Loading…
Reference in New Issue
Block a user