Wednesday, March 17, 2010

SSH Without Password

SSH login (and sftp) is a secure and convenient method of accessing data and services on remote computers. Sometimes we want to automate the secure log in. Since normally a SSH log in requires a password that corresponds to the user account on the remote computer, using SSH from a script presents a problem. Public/private certificates to the rescue!

Suppose we have a server that we want to access from scripts on two different computers. These scripts are executed periodically by cron jobs. We want to enable a no-password log in from those two computers while requiring a password SSH log in for all others. To do this, we must create a public/private key pair for each of the computers we wish to grant no-password log in privileges. The public key from each of these computers is then shared with the server we want to access. This cryptographically links the two local computers to the remote server.

The storage of these keys on both the local and remote computers is specific to user accounts. For example, suppose we have a local user account named 'getsoh' (get state of health). Every five minutes a cron job triggers a script belonging to the getsoh account that retrieves (using sftp or scp) a log on the remote server that is owned by the user 'createsoh'. We want to create the public/private key pair as user getsoh on the local computer and share the public key with the user createsoh on the remote computer. This is easy to do.
  • On the local machine as user 'getsoh', ensure that the ~/.ssh folder exists. If not create it (type: mkdir ~/.ssh). Ensure that ~/.ssh permissions are 0700.
  • Type: ssh-keygen -t rsa (accept all default settings, including an empty passphrase)
  • Two files (id_rsa and id_rsa.pub) should now be in your ~/.ssh folder.
  • On the remote machine as user 'createsoh', ensure that the folder ~/.ssh exists.
  • Copy the public key to the remote server (ex: remote.com) and append to the ~/.ssh/authorized_keys folder of user 'createsoh'. Type: cat ~/.ssh/id_rsa.pub | ssh createsoh@remote.com  'cat >> ~/.ssh/authorized_keys'
  • Remember to append to rather than overwrite the authorized_keys file in case other keys already are stored.
Remember that creating keys with an empty pass-phrase is a security risk. If someone were to retrieve your private key, they could use that to log in to the remote computers. The use of ssh-agent partially solves that risk by allowing you to use a non-empty pass-phrase and enter it only once, after which it is then cached for the duration of the session. This approach, however, cannot be used when ssh access is needed from a script run periodically by cron.

If the private key is stolen from the client, an unauthorized user will be able to login to the server hosting the public key. To minimize the risk of this occuring, an additional check can be placed in the public key on the server. At the very front of the key in the authorized_keys file, insert: from="client.net", where client.net is the client computer hostname or IP address. Wildcards are supported (i.e. *.clients.net). Multiple hosts/addresses can be used if separated by a comma. Make sure you put double quotes around the host/ip addresses.

If the only purpose of the ssh log in is to automatically run a script, additional restrictions can be defined that will increase security. Let's say that periodically, the client remotely accesses the server through ssh to copy a log file to a shared folder. Expanding on the "from" option mentioned previously, a "command" option can also be used to restrict what can be done when the automatic ssh log in occurs. Assuming that the "from" option is inserted at the front of the key in the server authorized_keys file, insert a comma and then the following:

command="~/getlog.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty

This option will run the ~/.getlog.sh command immediately after a SSH login with the key occurs and then exit.

Troubleshooting:
  •  Try the command: ssh -o PreferredAuthentications=publickey user@server.net
  • Ensure that all ~/.ssh folders have permissions of 0700
  • Ensure that the server ~/.ssh/authorized_keys file has permissions of 0600
  • Use ssh -v[vv] to generate verbose debug information. The the more 'v's the more verbose.

      Labels: , ,

      Wednesday, October 14, 2009

      Mounting SMB Shares on Ubuntu

      I have a 12+ year old Dell computer that's been faithfully chugging away in my basement as a file server running CentOS 4. Each user in the family has their own data directory on the server that is mounted on their Windows XP "My Documents" directory. Works great.

      I've started thinking of switching over to Ubuntu as the primary OS for our family's use and so am experimenting using VirtualBox and a Ubuntu virtual machine. By the way, VirtualBox's seamless mode has a big "WOW" factor. It allows you to run a guest operating system, in this case, Ubuntu, and the Windows XP host system using, essentially, the same desktop. It's very cool and very useful. But I diverge.

      As I mentioned, I have SAMBA shares sitting on the Dell file server and I want to mount each user's share onto their Ubuntu ~/Documents folder so they have exactly the same access as on the Window computers. I don't want to mess with NFS because then I have to worry about both NFS and SAMBA shares and I would prefer to have to deal with only one file sharing service.

      This should work using SAMBA shares from any computer running any operating system. First, ensure you have the correct packages on your Ubuntu system. From a Ubuntu terminal, type:
      sudo apt-get install smbfs smbclient
      Before trying to mount the remote SMB share, securely store your Ubuntu login credentials so that the share will automount at boot. This is done by using your favorite text editor to edit the file /root/.credentials. Enter the following lines in the file, substituting the correct SMB username and SMB password (this example uses a SMB username of barney, a SMB password of betty.
      username=barney
      password=betty
      
      Now make the credentials file root read-only by typing:
      chmod 0600 /root/.credentials
      Assuming the SAMBA server IP is 192.168.1.200, the remote SAMBA share is named barney, and barney's Ubuntu user id is 1000, enter the SMB share and mount point information in your /etc/fstab file as follows:
      //192.168.1.200/barney /home/barney/Documents smbfs \
              auto,credentials=/root/.credentials,uid=1000,umask=000,user 0 0
      

      To test, you can type:
      sudo mount -a
      or simply reboot.

      Labels: , ,

      Wednesday, September 23, 2009

      Hide Users on a Fedora 10 Login Screen

      You may want to hide the login ids of users on systems for privacy or security reasons. Although this is possible, the command is very unwieldy. Here's how you do it for Fedora 10.

      gconftool-2 --config-source xml:readwrite:/etc/gconf/gconf.xml.defaults --direct --type bool --set /apps/gdm/simple-greeter/disable_user_list true

      Ugly, but it works.

      Labels: ,

      Saturday, September 19, 2009

      NTP Server & Client Configs on Fedora 10

      On the server, ensure that there is the following line in the /etc/hosts file:
      127.0.0.1 localhost
      Also ensure that port 123/UDP is open.

      Then edit the /etc/ntp.conf file to look like this:
      # For more information about this file, see the man pages
      # ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).


      # Permit time synchronization with our time source, but do not

      # permit the source to query or modify the service on this system.

      restrict default kod nomodify notrap nopeer noquery

      restrict -6 default kod nomodify notrap nopeer noquery


      # Permit all access over the loopback interface. This could

      # be tightened as well, but to do so would effect some of

      # the administrative functions.
      restrict 127.0.0.1

      restrict -6 ::1


      # Use public servers from the pool.ntp.org project.

      # Please consider joining the pool (http://www.pool.ntp.org/join.html).

      #server 0.fedora.pool.ntp.org dynamic

      #server 1.fedora.pool.ntp.org dynamic

      #server 2.fedora.pool.ntp.org dynamic

      driftfile /var/lib/ntp/drift


      # Undisciplined Local Clock. This is a fake driver intended for backup

      # and when no outside source of synchronized time is available.
      server 127.127.1.0

      # local clock
      fudge
      127.127.1.0 stratum 10



      # Key file containing the keys and key identifiers used when operating
      # with symmetric key cryptography.
      keys /etc/ntp/keys
      On the server, enter:
      chkconfig ntpd on
      service ntpd on
      Then, set the date correctly on the server (date MMDDhhmm).

      On the client,
      ensure that there is the following line in the /etc/hosts file:
      127.0.0.1 localhost


      Edit the /etc/ntp.conf file to look like this, assuming that the local NTP server we just set up is named barney with an IP address of 10.8.0.1:


      # For more information about this file, see the man pages
      # ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).

      # Permit time synchronization with our time source, but do not
      # permit the source to query or modify the service on this system.
      restrict default kod nomodify notrap nopeer noquery
      restrict -6 default kod nomodify notrap nopeer noquery

      # Permit all access over the loopback interface. This could
      # be tightened as well, but to do so would effect some of
      # the administrative functions.
      restrict 127.0.0.1
      restrict -6 ::1

      driftfile /var/lib/ntp/drift

      # Hosts on local network are less restricted.
      restrict barney mask 255.255.255.0 nomodify notrap
      server barney

      # Key file containing the keys and key identifiers used when operating
      # with symmetric key cryptography.
      keys /etc/ntp/keys

      On the client, enter:
      chkconfig ntpd on
      service ntpd on
      If there is a large difference in times, you can quickly bring the client into close sync with the time server by typing:
      ntpdate barney
      You can see if the client is being updated by using the command:
      watch ntpq -p


      Labels: ,

      Friday, September 18, 2009

      RPM & YUM tricks



      So you're building a complex system that requires installing many software packages in RPM format and you keep having problems with dependencies, conflicts, and who knows what else. Here are some handy RPM commands that might come in useful.

      # extracts the contents of an RPM to disk
      rpm2cpio < packagename.rpm | cpio - ivd

      # list the contents of an RPM file
      rpm -qpi packagename.rpm

      # install all the RPMs in the current folder
      rpm -U *.rpm

      # don't install, but print out what would happen
      rpm -i --test list of RPM packages

      # replace existing files in another package even if there is a conflict
      rpm -i --replacefiles packagename.rpm

      # Removes the last 'n' RPMs. The example below uses last 15 RPMs.
      rpm -qa --last | head -15 | cut -d" " -f 1 | xargs rpm -e

      # test a group of RPMs for missing dependencies (or other problems)
      # definitely need to resolve "is needed by" errors
      mkdir /tmp/testdb
      rpm --initdb --dbpath /tmp/testdb
      cd packages folder
      rpm --test --dbpath /tmp/testdb -Uvh *.rpm
      rpm -rf /tmp/testdb



      # save the RPMs that are downloaded and installed by yum

      Edit the /etc/yum.conf file and change (or insert) keepcache=1


      # download only (don't install) RPMs using yum
      yum install yum-downloadonly
      yum update somepackage --downloadonly
      yum update somepackage --downloadonly --downloaddir=/tmp/newpkgs

      Labels: , ,

      Root is read-only?

      When you're doing serious work on Linux, sometimes things get broken and need to be fixed. If that something involves disks, you might be greeted with a screen at boot that says that there is a problem and that you should "Give root password for maintenance (or type Control-D for normal startup)". But when you type your root password and get the shell prompt, you can't do anything because the root is read-only. For instance, you might need to edit /etc/fstab or another configuration file to remove or comment out an offending line. But you can't save your changes because root is read-only. The command to fix this is simple:

      mount -n -o remount -t ext3 /dev/sda3 /

      Remember to enter the correct filesystem type (ext3 in this example) and the correct disk partition (/dev/sda3 in this example) and your problem should be solved.

      Labels: ,