Add password authentication for SSH
This commit is contained in:
parent
4f3d83f458
commit
3d3fbbcbd9
@ -55,7 +55,7 @@ It's possible to use a remote server as destination for the backup. Just use the
|
||||
For this to work, rsync must be installed on the server too.
|
||||
|
||||
### Server authentication
|
||||
Right now only authentication using SSH key works. The best way to handle the authentication is to have an ssh agent running on your system, otherwise if a passphrase is necessary to unlock the ssh key, it will be necessary to enter it more than once.
|
||||
The best way to handle the authentication is to have an ssh agent running on your system, otherwise if a passphrase is necessary to unlock the ssh key, it will be necessary to enter it more than once.
|
||||
If needed, it's possible to specify the ssh key location with the --keyfile argument or in the configuration file.
|
||||
|
||||
To be able to connect to the user's ssh agent when running simple_backup with sudo, make sure to preserve the SSH_AUTH_SOCK environment variable. For example:
|
||||
@ -65,3 +65,4 @@ sudo --preserve-env=SSH_AUTH_SOCK -s simple_backup [options]
|
||||
```
|
||||
|
||||
or by editing the sudoers file.
|
||||
If SSH key authentication is not available, password authentication will be used instead.
|
||||
|
@ -28,11 +28,13 @@ simple_backup \- Backup files and folders using rsync
|
||||
.RE
|
||||
.SH DESCRIPTION
|
||||
.BR simple_backup
|
||||
is a python script for performing backup of files and folders. It uses rsync to copy the files
|
||||
to the specified location. Parameters for the backup such as input files/directories, output
|
||||
location and files or folders to exclude can be specified
|
||||
is a python script for performing backup of files and folders.
|
||||
.P
|
||||
It uses rsync to copy the files to the specified location. Parameters for the backup such as
|
||||
input files/directories, output location and files or folders to exclude can be specified
|
||||
in a configuration file (default location $HOME/.config/simple_backup/simple_backup.conf)
|
||||
or directly on the command line.
|
||||
.P
|
||||
Parameters specified on the command line will override those in the configuration file.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
@ -61,7 +63,7 @@ Specify how many old backups (so excluding the current one) will be kept. The de
|
||||
is to keep them all (same as N=\-1)
|
||||
.TP
|
||||
.B \-\-host HOSTNAME
|
||||
Hostname of the server where to copy the files in case of remote backup through ssh
|
||||
Hostname of the server where to copy the files in case of remote backup through SSH
|
||||
.TP
|
||||
.B \-u, \-\-username USERNAME
|
||||
Username for connecting to the server in case of remote backup
|
||||
@ -88,10 +90,38 @@ Copy it to the default location ($HOME/.config/simple_backup) and edit it as nee
|
||||
It is possible to choose a directory on a remote server as destination for the backup. The files
|
||||
are copied by rsync through SSH. Server hostname and username must be specified, either in the
|
||||
configuration file, or on the command line (\(aq\-\-host\(aq and \(aq\-\-username\(aq options).
|
||||
Currently only authentication with SSH key has been tested. The easiest way to connect to the
|
||||
server is to use an ssh agent. Otherwise, if the SSH key is encrypted, it will be necessary
|
||||
to enter the passphrase more than once. It is possible to specify the SSH key to use with the
|
||||
option \(aq\-\-keyfile\(aq, if necessary.
|
||||
.SS AUTHENTICATION
|
||||
For authentication, it is possible to use SSH key or password.
|
||||
.P
|
||||
When using SSH key, the best way to connect to the server is to have an SSH agent running.
|
||||
Otherwise, if the SSH key is encrypted, it will be necessary to enter the passphrase more
|
||||
than once. It is possible to specify the SSH key to use with the option \(aq\-\-keyfile\(aq,
|
||||
if necessary.
|
||||
.P
|
||||
When running
|
||||
.B simple_backup
|
||||
with
|
||||
.B sudo,
|
||||
in order to connect to the user\(aq s SSH agent it is necessary to preserve the \(aq SSH_AUTH_SOCK\(aq environment variable, for example:
|
||||
.P
|
||||
.EX
|
||||
sudo --preserve-env=SSH_AUTH_SOCK -s simple_backup [options]
|
||||
.EE
|
||||
.P
|
||||
It is also possible to make this permanent by editing the
|
||||
.B sudoers
|
||||
file (see
|
||||
.B sudoers (5)
|
||||
)
|
||||
.P
|
||||
If SSH key authentication is not available, password authentication will be used instead.
|
||||
Note that in this case
|
||||
.B sshpass
|
||||
(if available) will be used to send the password to rsync, to avoid prompting the user for
|
||||
the password multiple
|
||||
times. This can pose some security risks, see
|
||||
.B sshpass (1)
|
||||
for details. For this reason, use SSH key authentication if possible.
|
||||
.SH SEE ALSO
|
||||
.BR rsync (1)
|
||||
.SH AUTHORS
|
||||
|
@ -10,13 +10,12 @@ Classes:
|
||||
MyFormatter
|
||||
Backup
|
||||
"""
|
||||
|
||||
# Import libraries
|
||||
import sys
|
||||
import os
|
||||
import warnings
|
||||
from functools import wraps
|
||||
from shutil import rmtree
|
||||
from shutil import rmtree, which
|
||||
import shlex
|
||||
import argparse
|
||||
import configparser
|
||||
@ -155,6 +154,8 @@ class Backup:
|
||||
self._remote = None
|
||||
self._err_flag = False
|
||||
self._ssh = None
|
||||
self._password_auth = False
|
||||
self._password = None
|
||||
|
||||
def check_params(self):
|
||||
"""Check if parameters for the backup are valid"""
|
||||
@ -325,13 +326,22 @@ class Backup:
|
||||
except paramiko.SSHException:
|
||||
pass
|
||||
|
||||
pkey = None
|
||||
password = None
|
||||
|
||||
if self.ssh_keyfile is None:
|
||||
logger.critical('Can\'t connect to the server. No authentication method available')
|
||||
try:
|
||||
password = getpass(f'{self.username}@{self.host}\'s password: ')
|
||||
ssh.connect(self.host, username=self.username, password=password)
|
||||
|
||||
return None
|
||||
self._password_auth = True
|
||||
os.environ['SSHPASS'] = password
|
||||
|
||||
return ssh
|
||||
except paramiko.SSHException as e:
|
||||
logger.critical('Can\'t connect to the server.')
|
||||
logger.critical(e)
|
||||
|
||||
return None
|
||||
|
||||
pkey = None
|
||||
|
||||
try:
|
||||
pkey = RSAKey.from_private_key_file(self.ssh_keyfile)
|
||||
@ -427,12 +437,16 @@ class Backup:
|
||||
|
||||
if euid == 0 and self.ssh_keyfile is not None:
|
||||
rsync = f'{rsync} -e \'ssh -i {self.ssh_keyfile}\''
|
||||
elif self._password_auth and which('sshpass'):
|
||||
rsync = f'{rsync} -e \'sshpass -e ssh -l {self.username}\''
|
||||
|
||||
args = shlex.split(rsync)
|
||||
|
||||
with Popen(args, stdin=PIPE, stdout=PIPE, stderr=STDOUT, shell=False) as p:
|
||||
output, _ = p.communicate()
|
||||
|
||||
del os.environ['SSHPASS']
|
||||
|
||||
if p.returncode != 0:
|
||||
self._err_flag = True
|
||||
|
||||
@ -444,7 +458,7 @@ class Backup:
|
||||
logger.info('rsync: %s', output[-3])
|
||||
logger.info('rsync: %s', output[-2])
|
||||
|
||||
if self._remote:
|
||||
if self._remote and not self._err_flag:
|
||||
_, stdout, _ = \
|
||||
self._ssh.exec_command(f'if [ -L "{self.output}/simple_backup/last_backup" ]; then echo "ok"; fi')
|
||||
|
||||
@ -458,7 +472,7 @@ class Backup:
|
||||
if err != '':
|
||||
logger.error(err)
|
||||
self._err_flag = True
|
||||
else:
|
||||
elif not self._err_flag:
|
||||
if os.path.islink(f'{self.output}/simple_backup/last_backup'):
|
||||
try:
|
||||
os.remove(f'{self.output}/simple_backup/last_backup')
|
||||
@ -478,7 +492,7 @@ class Backup:
|
||||
if err != '':
|
||||
logger.error(err)
|
||||
self._err_flag = True
|
||||
elif not self._remote:
|
||||
elif not self._err_flag:
|
||||
try:
|
||||
os.symlink(self._output_dir, f'{self.output}/simple_backup/last_backup', target_is_directory=True)
|
||||
except FileExistsError:
|
||||
|
Loading…
x
Reference in New Issue
Block a user