def test_dep_backup_file(): with settings(hosts=[H], host_string=HS, user=R, password=R): sudo('rm -rf /var/local/woven-backup') _backup_file('/etc/ssh/sshd_config') assert exists('/var/local/woven-backup/etc/ssh/sshd_config') sudo('rm -rf /var/local/woven-backup')
def restrict_ssh(rollback=False): """ Set some sensible restrictions in Ubuntu /etc/ssh/sshd_config and restart sshd UseDNS no #prevents dns spoofing sshd defaults to yes X11Forwarding no # defaults to no AuthorizedKeysFile %h/.ssh/authorized_keys uncomments PasswordAuthentication no and restarts sshd """ if not rollback: if server_state('ssh_restricted'): print env.host, 'Warning: sshd_config has already been modified. Skipping..' return False sshd_config = '/etc/ssh/sshd_config' if env.verbosity: print env.host, "RESTRICTING SSH with "+sshd_config filename = 'sshd_config' if not exists('/home/%s/.ssh/authorized_keys'% env.user): #do not pass go do not collect $200 print env.host, 'You need to upload_ssh_key first.' return False _backup_file(sshd_config) context = {"HOST_SSH_PORT": env.HOST_SSH_PORT} upload_template('woven/ssh/sshd_config','/etc/ssh/sshd_config',context=context,use_sudo=True) # Restart sshd sudo('/etc/init.d/ssh restart') # The user can modify the sshd_config file directly but we save if env.INTERACTIVE and contains('#PasswordAuthentication no','/etc/ssh/sshd_config',use_sudo=True): c_text = 'Woven will now remove password login from ssh, and use only your ssh key. \n' c_text = c_text + 'CAUTION: please confirm that you can ssh %s@%s -p%s from a terminal without requiring a password before continuing.\n'% (env.user, env.host, env.port) c_text += 'If you cannot login, press enter to rollback your sshd_config file' proceed = confirm(c_text,default=False) if not env.INTERACTIVE or proceed: #uncomments PasswordAuthentication no and restarts uncomment(sshd_config,'#(\s?)PasswordAuthentication(\s*)no',use_sudo=True) sudo('/etc/init.d/ssh restart') else: #rollback print env.host, 'Rolling back sshd_config to default and proceeding without passwordless login' _restore_file('/etc/ssh/sshd_config', delete_backup=False) sed('/etc/ssh/sshd_config','Port '+ str(env.DEFAULT_SSH_PORT),'Port '+str(env.HOST_SSH_PORT),use_sudo=True) sudo('/etc/init.d/ssh restart') return False set_server_state('ssh_restricted') return True else: #Full rollback _restore_file('/etc/ssh/sshd_config') if server_state('ssh_port_changed'): sed('/etc/ssh/sshd_config','Port '+ str(env.DEFAULT_SSH_PORT),'Port '+str(env.HOST_SSH_PORT),use_sudo=True) sudo('/etc/init.d/ssh restart') sudo('/etc/init.d/ssh restart') set_server_state('ssh_restricted', delete=True) return True
def uncomment_sources(rollback=False): """ Uncomments universe sources in /etc/apt/sources.list if necessary #(.?)deb(.*)http:(.*)universe """ if not rollback: if contains(filename='/etc/apt/sources.list',text='#(.?)deb(.*)http:(.*)universe'): if env.verbosity: print env.host, "UNCOMMENTING universe SOURCES in /etc/apt/sources.list" _backup_file('/etc/apt/sources.list') uncomment('/etc/apt/sources.list','#(.?)deb(.*)http:(.*)universe',use_sudo=True) else: _restore_fie('/etc/apt/sources.list')
def upload_ssh_key(rollback=False): """ Upload your ssh key for passwordless logins """ user_ssh_dir = os.path.join(deployment_user_home(), '.ssh') auth_keys = os.path.join(user_ssh_dir, 'authorized_keys') if not rollback: local_user = getpass.getuser() host = socket.gethostname() u = '@'.join([local_user,host]) u = 'ssh-key-uploaded-%s'% u if not env.overwrite and server_state(u): return if not exists('.ssh'): run('mkdir .ssh') #determine local .ssh dir home = os.path.expanduser('~') ssh_dsa = os.path.join(home,'.ssh/id_dsa.pub') ssh_rsa = os.path.join(home,'.ssh/id_rsa.pub') if env.KEY_FILENAME: if not os.path.exists(env.KEY_FILENAME): print "ERROR: The specified KEY_FILENAME (or SSH_KEY_FILENAME) %s does not exist"% env.KEY_FILENAME sys.exit(1) else: ssh_key = env.KEY_FILENAME elif os.path.exists(ssh_dsa): ssh_key = ssh_dsa elif os.path.exists(ssh_rsa): ssh_key = ssh_rsa else: ssh_key = '' if ssh_key: ssh_file = open(ssh_key,'r').read() ssh_file = ssh_file.strip() # remove any trailing \n's if exists(auth_keys): _backup_file(auth_keys) if env.verbosity: print env.host, "UPLOADING SSH KEY" append(ssh_file,auth_keys) #append prevents uploading twice set_server_state(u) return else: if exists(auth_keys+'.wovenbak'): _restore_file(auth_keys) else: #no pre-existing keys remove the .ssh directory sudo('rm -rf ' + user_ssh_dir) return
def restrict_ssh(rollback=False): """ Set some sensible restrictions in Ubuntu /etc/ssh/sshd_config and restart sshd UseDNS no #prevents dns spoofing sshd defaults to yes X11Forwarding no # defaults to no AuthorizedKeysFile %h/.ssh/authorized_keys uncomments PasswordAuthentication no and restarts sshd """ if not rollback: if server_state('ssh_restricted'): return False sshd_config = '/etc/ssh/sshd_config' if env.verbosity: print env.host, "RESTRICTING SSH with "+sshd_config filename = 'sshd_config' if not exists('/home/%s/.ssh/authorized_keys'% env.user): #do not pass go do not collect $200 print env.host, 'You need to upload_ssh_key first.' return False _backup_file(sshd_config) context = {"HOST_SSH_PORT": env.HOST_SSH_PORT} upload_template('woven/ssh/sshd_config','/etc/ssh/sshd_config',context=context,use_sudo=True) # Restart sshd sudo('/etc/init.d/ssh restart') # The user can modify the sshd_config file directly but we save proceed = True if not env.key_filename and (env.DISABLE_SSH_PASSWORD or env.INTERACTIVE) and contains('/etc/ssh/sshd_config','#PasswordAuthentication no',use_sudo=True): print "WARNING: You may want to test your node ssh login at this point ssh %s@%s -p%s"% (env.user, env.host, env.port) c_text = 'Would you like to disable password login and use only ssh key authentication' proceed = confirm(c_text,default=False) if not env.INTERACTIVE or proceed or env.DISABLE_SSH_PASSWORD: #uncomments PasswordAuthentication no and restarts uncomment(sshd_config,'#(\s?)PasswordAuthentication(\s*)no',use_sudo=True) sudo('/etc/init.d/ssh restart') set_server_state('ssh_restricted') return True else: #Full rollback _restore_file('/etc/ssh/sshd_config') if server_state('ssh_port_changed'): sed('/etc/ssh/sshd_config','Port '+ str(env.DEFAULT_SSH_PORT),'Port '+str(env.HOST_SSH_PORT),use_sudo=True) sudo('/etc/init.d/ssh restart') sudo('/etc/init.d/ssh restart') set_server_state('ssh_restricted', delete=True) return True
def upload_ssh_key(rollback=False): """ Upload your ssh key for passwordless logins """ auth_keys = "/home/%s/.ssh/authorized_keys" % env.user if not rollback: local_user = getpass.getuser() host = socket.gethostname() u = "@".join([local_user, host]) u = "ssh-key-uploaded-%s" % u if not env.overwrite and server_state(u): return if not exists(".ssh"): run("mkdir .ssh") # Determine local .ssh dir. home = os.path.expanduser("~") ssh_key = None upload_key = True ssh_dsa = os.path.join(home, ".ssh/id_dsa.pub") ssh_rsa = os.path.join(home, ".ssh/id_rsa.pub") if env.key_filename and env.INTERACTIVE: upload_key = confirm( "Would you like to upload your personal key " "in addition to %s" % str(env.key_filename), default=True ) if upload_key: if os.path.exists(ssh_dsa): ssh_key = ssh_dsa elif os.path.exists(ssh_rsa): ssh_key = ssh_rsa if ssh_key: ssh_file = open(ssh_key, "r").read() if exists(auth_keys): _backup_file(auth_keys) if env.verbosity: print env.host, "UPLOADING SSH KEY" # Append prevents uploading twice. append(auth_keys, ssh_file) set_server_state(u) return else: if exists(auth_keys + ".wovenbak"): _restore_file("/home/%s/.ssh/authorized_keys" % env.user) else: # No pre-existing keys, so remove the .ssh directory. sudo("rm -rf /home/%s/.ssh") return
def upload_ssh_key(rollback=False): """ Upload your ssh key for passwordless logins """ auth_keys = '/home/%s/.ssh/authorized_keys'% env.user if not rollback: local_user = getpass.getuser() host = socket.gethostname() u = '@'.join([local_user,host]) u = 'ssh-key-uploaded-%s'% u if not env.overwrite and server_state(u): return if not exists('.ssh'): run('mkdir .ssh') #determine local .ssh dir home = os.path.expanduser('~') ssh_dsa = os.path.join(home,'.ssh/id_dsa.pub') ssh_rsa = os.path.join(home,'.ssh/id_rsa.pub') if env.KEY_FILENAME: if not os.path.exists(env.KEY_FILENAME): print "ERROR: The specified KEY_FILENAME (or SSH_KEY_FILENAME) %s does not exist"% env.KEY_FILENAME sys.exit(1) else: ssh_key = env.KEY_FILENAME elif os.path.exists(ssh_dsa): ssh_key = ssh_dsa elif os.path.exists(ssh_rsa): ssh_key = ssh_rsa else: ssh_key = '' if ssh_key: ssh_file = open(ssh_key,'r').read() if exists(auth_keys): _backup_file(auth_keys) if env.verbosity: print env.host, "UPLOADING SSH KEY" append(ssh_file,auth_keys) #append prevents uploading twice set_server_state(u) return else: if exists(auth_keys+'.wovenbak'): _restore_file('/home/%s/.ssh/authorized_keys'% env.user) else: #no pre-existing keys remove the .ssh directory sudo('rm -rf /home/%s/.ssh') return
def set_timezone(rollback=False): """ Set the time zone on the server using Django settings.TIME_ZONE """ if not rollback: if contains(text=env.TIME_ZONE,filename='/etc/timezone',use_sudo=True): return False if env.verbosity: print env.host, "CHANGING TIMEZONE /etc/timezone to "+env.TIME_ZONE _backup_file('/etc/timezone') sudo('echo %s > /tmp/timezone'% env.TIME_ZONE) sudo('cp -f /tmp/timezone /etc/timezone') sudo('dpkg-reconfigure --frontend noninteractive tzdata') else: _restore_fie('/etc/timezone') sudo('dpkg-reconfigure --frontend noninteractive tzdata') return True
def add_repositories(): """ Adds additional sources as defined in LINUX_PACKAGE_REPOSITORIES. """ if not env.overwrite and env.LINUX_PACKAGE_REPOSITORIES == server_state('linux_package_repositories'): return if env.verbosity: print env.host, "UNCOMMENTING SOURCES in /etc/apt/sources.list and adding PPAs" if contains(filename='/etc/apt/sources.list',text='#(.?)deb(.*)http:(.*)universe'): _backup_file('/etc/apt/sources.list') uncomment('/etc/apt/sources.list','#(.?)deb(.*)http:(.*)universe',use_sudo=True) install_package('python-software-properties') for p in env.LINUX_PACKAGE_REPOSITORIES: sudo('add-apt-repository %s'% p) if env.verbosity: print 'added source', p set_server_state('linux_package_repositories',env.LINUX_PACKAGE_REPOSITORIES)
def upload_ssh_key(rollback=False): """ Upload your ssh key for passwordless logins """ auth_keys = '/home/%s/.ssh/authorized_keys'% env.user if not rollback: local_user = getpass.getuser() host = socket.gethostname() u = '@'.join([local_user,host]) u = 'ssh-key-uploaded-%s'% u if not env.overwrite and server_state(u): return if not exists('.ssh'): run('mkdir .ssh') #determine local .ssh dir home = os.path.expanduser('~') ssh_key = None upload_key = True ssh_dsa = os.path.join(home,'.ssh/id_dsa.pub') ssh_rsa = os.path.join(home,'.ssh/id_rsa.pub') if env.key_filename and env.INTERACTIVE: upload_key = confirm('Would you like to upload your personal key in addition to %s'% str(env.key_filename), default=True) if upload_key: if os.path.exists(ssh_dsa): ssh_key = ssh_dsa elif os.path.exists(ssh_rsa): ssh_key = ssh_rsa if ssh_key: ssh_file = open(ssh_key,'r').read() if exists(auth_keys): _backup_file(auth_keys) if env.verbosity: print env.host, "UPLOADING SSH KEY" append(auth_keys,ssh_file) #append prevents uploading twice set_server_state(u) return else: if exists(auth_keys+'.wovenbak'): _restore_file('/home/%s/.ssh/authorized_keys'% env.user) else: #no pre-existing keys remove the .ssh directory sudo('rm -rf /home/%s/.ssh') return
def setup_ufw(): """ Setup basic ufw rules just for ssh login """ if not env.ENABLE_UFW: return ufw_state = server_state("ufw_installed") if ufw_state and not env.overwrite or ufw_state == str(env.HOST_SSH_PORT): return # Check for actual package. ufw = run("dpkg -l | grep 'ufw' | awk '{print $2}'").strip() if not ufw: if env.verbosity: print env.host, "INSTALLING & ENABLING FIREWALL ufw" install_package("ufw") if env.verbosity: print env.host, "CONFIGURING FIREWALL ufw" # Upload basic woven (ssh) ufw app config. upload_template( "/".join(["woven", "ufw.txt"]), "/etc/ufw/applications.d/woven", {"HOST_SSH_PORT": env.HOST_SSH_PORT}, use_sudo=True, backup=False, ) sudo("chown root:root /etc/ufw/applications.d/woven") with settings(warn_only=True): if not ufw_state: sudo("ufw allow woven") else: sudo("ufw app update woven") _backup_file("/etc/ufw/ufw.conf") # Enable ufw. sed("/etc/ufw/ufw.conf", "ENABLED=no", "ENABLED=yes", use_sudo=True, backup="") with settings(warn_only=True): output = sudo("ufw reload") if env.verbosity: print output set_server_state("ufw_installed", str(env.HOST_SSH_PORT)) return
def setup_ufw(rollback=False): """ Setup ufw and apply rules from settings UFW_RULES You can add rules and re-run setup_ufw but cannot delete rules or reset by script since deleting or reseting requires user interaction See Ubuntu Server documentation for more about UFW. """ if not rollback: #TODO - Optimize to store & compare existing rules to stop unecessary reloads #Should be able to do something with the ufw status command to store the rules #ufw_rules = sudo("ufw status | awk '/tcp|udp/ {print $1,$2,$3}'").split('\n') ufw = run("dpkg -l | grep '%s' | awk '{print $2}'").strip() #It would be nice to handle an existing installation but until ufw can easily #predefine rules in a conf we'll need to just mark it if woven installs it if not ufw: if env.verbosity: print env.host, "INSTALLING & ENABLING FIREWALL ufw" apt_get_install('ufw') set_server_state('ufw_installed') sudo('ufw allow %s/tcp'% env.port) #ssh port u = set([]) if env.roles: for r in env.roles: u = u | set(env.ROLE_UFW_RULES.get(r,[])) if not u: u = env.UFW_RULES else: u = env.UFW_RULES for rule in u: if rule: if env.verbosity: print ' *',rule sudo('ufw '+rule) _backup_file('/etc/ufw/ufw.conf') sed('/etc/ufw/ufw.conf','ENABLED=no','ENABLED=yes',use_sudo=True) sudo('ufw reload') else: #if it was installed by woven remove it else leave it the hell alone if server_state('ufw_installed'): sudo('ufw disable') apt_get_purge('ufw') set_server_state('ufw_installed',delete=True)
def setup_ufw(): """ Setup basic ufw rules just for ssh login """ if not env.ENABLE_UFW: return ufw_state = server_state('ufw_installed') if ufw_state and not env.overwrite or ufw_state == str(env.HOST_SSH_PORT): return #check for actual package ufw = run("dpkg -l | grep 'ufw' | awk '{print $2}'").strip() if not ufw: if env.verbosity: print env.host, "INSTALLING & ENABLING FIREWALL ufw" install_package('ufw') if env.verbosity: print env.host, "CONFIGURING FIREWALL ufw" #upload basic woven (ssh) ufw app config upload_template('/'.join(['woven','ufw.txt']), '/etc/ufw/applications.d/woven', {'HOST_SSH_PORT':env.HOST_SSH_PORT}, use_sudo=True, backup=False) sudo('chown root:root /etc/ufw/applications.d/woven') with settings(warn_only=True): if not ufw_state: sudo('ufw allow woven') else: sudo('ufw app update woven') _backup_file('/etc/ufw/ufw.conf') #enable ufw sed('/etc/ufw/ufw.conf','ENABLED=no','ENABLED=yes',use_sudo=True, backup='') with settings(warn_only=True): output = sudo('ufw reload') if env.verbosity: print output set_server_state('ufw_installed',str(env.HOST_SSH_PORT)) return
def upload_ssh_key(rollback=False): """ Upload your ssh key for passwordless logins """ auth_keys = '/home/%s/.ssh/authorized_keys'% env.user if not rollback: if not exists('.ssh'): run('mkdir .ssh') #determine local .ssh dir home = os.path.expanduser('~') ssh_dsa = os.path.join(home,'.ssh/id_dsa.pub') ssh_rsa = os.path.join(home,'.ssh/id_rsa.pub') if os.path.exists(ssh_dsa): ssh_key = ssh_dsa elif os.path.exists(ssh_rsa): ssh_key = ssh_rsa else: ssh_key = '' if ssh_key: ssh_file = open(ssh_key,'r').read() if exists(auth_keys): _backup_file(auth_keys) if env.verbosity: print env.host, "UPLOADING SSH KEY if it doesn't already exist on host" append(ssh_file,auth_keys) #append prevents uploading twice return else: if exists(auth_keys+'.wovenbak'): _restore_file('/home/%s/.ssh/authorized_keys'% env.user) else: #no pre-existing keys remove the .ssh directory sudo('rm -rf /home/%s/.ssh') return
def restrict_ssh(rollback=False): """ Set some sensible restrictions in Ubuntu /etc/ssh/sshd_config and restart sshd. UseDNS no # Prevents dns spoofing sshd defaults to yes X11Forwarding no # Defaults to no AuthorizedKeysFile %h/.ssh/authorized_keys Also uncomment PasswordAuthentication no and restart sshd. """ if not rollback: if server_state("ssh_restricted"): return False sshd_config = "/etc/ssh/sshd_config" if env.verbosity: print env.host, "RESTRICTING SSH with " + sshd_config if not exists("/home/%s/.ssh/authorized_keys" % env.user): # Do not pass go, do not collect $200. print env.host, "You need to upload_ssh_key first." return False _backup_file(sshd_config) context = {"HOST_SSH_PORT": env.HOST_SSH_PORT} upload_template("woven/ssh/sshd_config", "/etc/ssh/sshd_config", context=context, use_sudo=True) # Restart sshd. sudo("/etc/init.d/ssh restart") # The user can modify the sshd_config file directly but we save. proceed = True if ( not env.key_filename and (env.DISABLE_SSH_PASSWORD or env.INTERACTIVE) and contains("/etc/ssh/sshd_config", "#PasswordAuthentication no", use_sudo=True) ): print "WARNING: You may want to test your node ssh login " "at this point ssh %s@%s -p%s" % ( env.user, env.host, env.port, ) c_text = "Would you like to disable password login and use " "only ssh key authentication" proceed = confirm(c_text, default=False) if not env.INTERACTIVE or proceed or env.DISABLE_SSH_PASSWORD: # Uncomments PasswordAuthentication no and restarts. uncomment(sshd_config, "#(\s?)PasswordAuthentication(\s*)no", use_sudo=True) sudo("/etc/init.d/ssh restart") set_server_state("ssh_restricted") return True else: # Full rollback. _restore_file("/etc/ssh/sshd_config") if server_state("ssh_port_changed"): sed( "/etc/ssh/sshd_config", "Port " + str(env.DEFAULT_SSH_PORT), "Port " + str(env.HOST_SSH_PORT), use_sudo=True, ) sudo("/etc/init.d/ssh restart") sudo("/etc/init.d/ssh restart") set_server_state("ssh_restricted", delete=True) return True