Archive for 'Linux'

Home » Linux

Restricting and Automating User Commands Through SSH and the authorized_keys File

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

Previously I explored how to limit a user’s ability to runs commands with sudo. As a tangential topic, I needed to restrict the commands that a user account had access to when they connected to the server via SSH. Specifically, I needed just a few commands to be strung together and executed every time this account connected.

The mechanism that I used to do this was with the authorized_keys file. For a thorough explanation of that file, take a peak at the man page for sshd. To explain it very simply, the authorized_keys file holds the public keys of other users/systems that are allowed to connect to that machine. For example, I place my main user account’s public RSA key into the authorized_keys file on the Linux servers that I manage. When I connect to the remote servers using SSH, it checks to see if I’m who I say I am by challenging me with the public key that it has stored. The user account on my laptop uses the private key to validate itself (yes, the private key is password protected) and I am then allowed to haxor on the servers to my heart’s content.

Here’s an example of a public key:

ssh-rsa AAAB3NzaC1yc2EAAAADAQABAAABAQDclBxY7lOaolHGaogdcc9GaTQLWMcn2PK4hnQfWlJgeeGqgS66jL4XJyiR9HcgaebBW88Z2sevUxd7g25WhuuRAazfOcElEaE+h6MMPZ94gHY+x+iVAdlNKxLT/bTvCUXLEft/yZFpnknnv7jX4ChfSiII9OiAiCzuSdyHt1/1LgEHgvDIwKMzvTgImm5X/3IhtOitjJY3Q6yhKQ6LdenQtG/v+ANqKe6opDuUKc3k9hRmj7aHROxL52paQTEgEMoVLbIoZY4/yGUzmrZQU45jNqMrbXdAxG4XexZxb7bpTLu91s0DJQGx43JNXwhJVinPgxHLmfyoCSqR1WPqn8E3 testuser@testserver

The public key, when placed in a system’s authorized_keys file, can have some extra tidbits added to it that sshd honors. An SSH protocol 2 public key follows this format:

options, keytype, base64-encoded key, comment

In the above public key, you see the keytype as ‘ssh-rsa’ followed by a space, then the key itself followed by a space and finally a comment, which in this case is a username and hostname combination. That’s a helpful hint to know who this key supposedly belongs to. Notice that there are no options included in the above key, which would come before the keytype.

Some of the options that are available to be parsed by sshd include:

  • environment= Changes an environmental variable for the user that is on the receiving end of the connection.
  • from= Only allows connections that use this public key to be initiated from certain hosts. Helpful for the extremely paranoid or the very security conscious (the only difference between the two being pay grade).
  • no-X11-forwarding Because we don’t need users installing xorg and then browsing the web on a remote instance of Chrome.

There are plenty of other options, however the final one that I’ll mention is the most crucial to this topic: command="command"

With the command= option, you can cause a command to be run immediately upon a successful connection to a remote host. Once the command is run, the connection is closed. Notice how that works. The command is immediately run and then once the command finishes, the connection is closed. This is not something that you’d want to do to a key that is intended to be used interactively by a human.

What could this be good for? In my specific scenario, I am using a backup tool that moves all of the data to stdout which is then piped to ssh for a secure transfer to remote storage. The remote connection would normally look like this: ssh remoteuser@remoteserver ” cat > backupfile.zip” However, if I edit the authorized keys file, I can restrict the incoming ssh connection to only be allowed to use that specific command.

It’s just another layer of security to keep people from doing things that they shouldn’t be doing. Have different ways of achieving a similar goal? Any caveats you know about? Let me know in the comments.



11MAY
2
Tweet

How to Make a Bootable CentOS 6 USB Drive

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

When making a bootable USB drive to install CentOS 6 from, you will need two primary partitions, one of them marked with the boot flag. One partition will be the boot partition and one will be a data partition that has the ISO file on it. As of this blog post, to make a CentOS 6 bootable USB drive, you’ll need a USB drive that has a little more than twice the space that your ISO file itself takes up. There is a bug that requires the ISO’s contents to be on the boot partition and the .iso file itself to be on the data partition. In essence you’re duplicating the ISO file and you still need some space left over for bootloader information. In my case, I’m using the minimal CentOS image, so space requirements are under 1GB.

At this point, go out and grab the CentOS ISO that interests you. Have it on your filesystem because we’ll be mounting it and copying some files from it. Once you’ve got the ISO you can move on to partitioning the drive.

Partitioning

First, you’ll want to partition the USB drive. We’ll be using plain ol’ MBR style partition tables and two primary partitions. I’m not going to hand-hold you through this part of the process. Use whatever partitioning tool you want and follow the guidelines below. GParted is fine if you use Gnome, parted is great if you want to use a shell, and fdisk works on both Windows and *NIX environments.

The partition layout will be thus:

  1. A primary partition that uses the FAT16 filesystem and is at least as big as your ISO plus about 50MB. You need to give it the boot flag.
  2. A primary partition that uses ext2 and is at least as big as your ISO. Preferably you’ll just use up the rest of your USB drive’s free space for this partition.

Once your partitions are set up, we’ve got some file moving to do.

Setting the Filesystems Up

You’ll want to mount your two partitions so that you can access them. In my case, the first partition (the FAT16 boot partition) is /dev/sdc1 and the data partition (the one formatted in ext2) is /dev/sdc2. I’ve mounted sdc1 as /mnt/usbboot and sdc2 as /mnt/usbdata. I will be using that nomenclature throughout the rest of this post.

You’ll also want to mount your CentOS ISO as a filesystem because we need to copy some files off of it. In my case, I ran mount -o loop /path/to/iso/file.iso /mnt/centosiso and will be using /mnt/centosiso in my examples below. Now that we’ve got all of our filesystems mounted, we’ll start the procedures.

First, go to the mounted CentOS iso and copy the /isolinux directory to the boot partition of the USB drive.

cp -r /mnt/centosiso/isolinux /mnt/usbboot

Rename the isolinux folder on the USB drive to syslinux

mv /mnt/usbboot/isolinux /mnt/usbboot/syslinux

Rename the isolinux.cfg file to syslinux.cfg

mv /mnt/usbboot/syslinux/isolinux.cfg /mnt/usbboot/syslinux/syslinux.cfg

Now we need to copy the contents of the /mnt/centosiso/images folder to the USB boot partition. Notice that I emphasis that this is a copy of the contents within the ISO’s images folder. A little later on we’ll be copying over the entire ISO as a file.

cp -r /mnt/centosiso/images /mnt/usbboot

Finally, we copy the .iso file itself to the data partition (not the boot partition that we were just working with!):

cp /path/to/iso/file.iso /mnt/usbdata

Once all that is done, we have to install a bootloader. I’ll use the simple syslinux loader. We want to use our smaller volume (the one that we set the boot flag on up in the partitioning section) as the target for the syslinux command.

syslinux -i /dev/sdc1

Now, we dismount our USB drive and test it out by booting from it on another system!

 


Finoto!

You should now have a bootable CentOS 6 USB drive. CentOS 6 is somewhat unique as a result of the bug that requires the images directory to be included on the boot partition, but other than that it’s relatively straight forward.



4MAY
0
Tweet

Solving Error “open of DOCTYPE failed: No such file or directory” When Using rpm -i

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

My Problem:

Attempting to install an RPM using the rpm -i command causes a series of errors:

error: open of <!DOCTYPE failed: No such file or directory
error: open of HTML failed: No such file or directory
error: open of PUBLIC failed: No such file or directory

The shell may hang and not return control to you.

It looks like it’s trying to parse an HTML document as a series of commands. Let’s think about that for a moment, shall we?

The Solution:

You are not attempting to install an rpm file, you are attempting to install a web page. Most likely either a redirect or 404 error page. Don’t believe me? Use cat to view the rpm file. In my case, trying to install rpmforge as a repo, I used curl to get what I thought was the proper rpm, however in reality I was retrieving the following:

$ cat rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://rpmforge.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm">here</a>.</p>
<hr>
<address>Apache/2.2.3 (Red Hat) Server at pkgs.repoforge.org Port 80</address>
</body></html>

Once you find the proper RPM file, I’m sure the installation will proceed without a hitch.



23APR
2
Tweet

How to Restrict a User’s sudo Rights to Only Specific Commands

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

The Task

I have a situation on a CentOS server where I need to grant one low privileged user account the ability to run a single command as root. Here’s how I did it:

Enter visudo and the sudoers File

This probably deserves its own post, but for now let it suffice to know that if you are editing the sudoers file, you need to use visudo. It checks your syntax before saving the file which will prevent you from swearing like a drunken stevedore in between hysterical crying fits.

Run visudo as root and scroll down to the section that assigned rights to user accounts. You’ll almost certainly see see a line that says

root ALL=(ALL) ALL

That’s the beginning of the section that we’re interested in. But, what does that even mean? Let’s talk about that before we edit anything.

The syntax for the user lines in the sudoers file follows this syntax:

who host=(accounts) commands

Broken down, that means:

  • who: the account that is having its ability to use sudo privileges modified
  • host: the system that the account is able to run these sudo commands on (the sudoers file can be shared across multiple computers, so that’s when this would come into play)
  • accounts: what other accounts on the machine the user running sudo can act as
  • commands: the commands that the account represented by who can run as sudo

That means root ALL=(ALL) ALL is broken down thusly: The root account can use sudo on all computers that have this sudoers file and assume the identity of any of the accounts on those machines to perform any command that is available on them.

There are a few other additional options that can be placed on the line to further define each user’s sudo privileges. I won’t go into detail about those options (mostly because I just learned about them the other day and I’m still clueless), but you can read much more about the whole thing using its man pages.

The specific option that I’m interested in is the NOPASSWD option. You see, I need to call sudo to run a specific command as root within a script and not be prompted for a password. In that case, I place the NOPASSWD option just before the commands that I want use as root without a password. It would look something like this:

backupuser ALL=(ALL) NOPASSWD: /usr/bin/backuptool

And that is how I restricted an account’s ability to use one single command as root using sudo without a password. Any thoughts? Caveats? The sudoers file is a behemoth invention that can do quite a few different things. Let me know your ideas below.



11APR
9
Tweet

What Version of Ubuntu am I Running?

Posted in: SysAdmin
  |  by: pauska
Tags: Linux, Ubuntu

(Today’s post is by guest author Erik Skålerud!)

Following up on Wesley’s post “What Version of CentOS / RedHat am I running?” and also to answer a twitter question from Barry Morrison – here’s how you quickly check what version of Ubuntu you’re running.

Both of the following methods should give you identical results.

Method #1

lsb_release -a

The result should be similar to this depending on your version/release:

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 10.04.4 LTS
Release:        10.04
Codename:       lucid

Method #2

cat /etc/lsb-release

Result (again, depending on version/release):

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.4 LTS"



5APR
2
Tweet

How I Learned to Tolerate White on Fuscia

Posted in: Productivity, SysAdmin
  |  by: ScottPack
Tags: Linux

(Today’s post is by information security analyst Scott Pack!)

One of the worst problems I have with tabbed consoles is knowing exactly which console I’m working in. Sure, I can simply look at either the shell’s title, or the prompt, but I still inevitably will type a command into the wrong console. Normally this will result in something more akin to “file not found” because you catted the wrong file, rather than “Now running koan on all servers” because you did something in mcollective prod instead of test. While chatting up a guy at work about this problem we threw around changing the background color depending on which system you’re on.

This is one of those things that’s a little trickier than one might think at first blush. For instance, my first thought was to overload the ssh operator and make the changes client side. This works for me since I use cygwin as my ssh client and proxy through an aggregator (see this ServerFault answer about proxying</shill>). My coworker, however, uses puttycm which pretty much excludes any kind of local overloading. In the end, I opted to have the colorization occur on login. This made the process more portable, but it also meant that I have to make changes to my ~/.bashrc on every system.

In the end, I wanted this setup to work for both of our environments. So for my uses I wanted the background to get reset whenever I logged off a remote system, so that if I *did* manually ssh from one system to another, the background color should always be correct no matter what else I’ve been doing. So the colors needed to be set on login, which is easy, and also whenever ssh exits (I suppose I should also account for telnet/rsh but I really don’t want to). To that end, I decided to make the colorization a separate function so it could easily be reused.

It’s also worth noting that this was designed for a system running bash-3.x. If you’re in an entirely bash-4.x environment we can use an associative array, which works like a perl hash. Since I still deal with a lot of RHEL5 systems, which still uses bash-3.x, I had to code to it. To account for this I had to do some odd stuff with the array that basically amounts to magic.

Without further ado, below is everything you’ll need to add to your ~/.bashrc file to make this garbage work. With any luck, the comments are sufficient to explain.

function setcolor {
# Set up the colormap using hex codes for the colors
  colormap=( "node1:#330000"
             "node2:#003300"
             "node3:#330033"
             "node4:#333300"
             "node5:#FF0000"
             "node6:#0000FF" )
# Generate my own short hostname, i.e. turn node1.example.com into node1
  short=`echo ${HOSTNAME} | sed "s/\..*$//"`
color="#000000" # Set default color to black
# Iterate through the colormap looking for the hostname. Also, some bash magic.
  for host in ${colormap[@]}; do
    if [[ ${host%%:*} == ${short} ]]; then
      color=${host##*:}
    fi
  done
# Wrap the color in the xterm escape sequences to set the background color
  echo -ne "33]11;${color}07" # Set the background color
}
# Only run the setcolor function if we are using xterm or xterm-color as our termtype
if [ $TERM = "xterm" ]; then
  export TERM="xterm-color"
  setcolor
elif [ $TERM = "xterm-color" ]; then
  setcolor
fi
# Replaces the shell title with the name of the host we are sshing to
function ssh {
echo -ne "33]0;${1}07"     # Set the terminal title to the host we are sshing to
  /usr/bin/ssh $1 $2 $3
  setcolor  # Once ssh exits, reset the color back to what it should be
}



3APR
0
Tweet

What Version of Parallels Plesk am I Running on my Linux Server?

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

Over the years, I have had to manage some client-facing servers that run Parallels Plesk on top of a Linux OS. I often need to see exactly what version and build number is running on the server. Using a shell, there are two ways to determine what version of Parallels Plesk is running.

Method 1:

cat /usr/local/psa/version

The version file is a simple ASCII text file that has information on the currently running version of Plesk. In my case, the result looked like this:

10.3.1 CentOS 5 1013110726.09

Method 2:

rpm -q psa

This method queries the RPM database for the psa package, which is Parallels Plesk. In my case, the result looked like this:

psa-10.3.1-cos5.build1012110718.17



22MAR
0
Tweet

What Version of CentOS / RedHat am I running?

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

Torn from the pages of “This is so simple I forget it even after doing it a hundred times.”

UPDATE (because I’m a noob):

As is shown in the comments by Scott Pack and Kenny Rasschaert, my hacktastic way of finding a CentOS machine’s specific release isn’t the best way to do things. It’s best to check the release package:

rpm -qa | grep release

Of course, as Chris S of ServerFault fame points out below, uname -a is useful as well. It shows the build number of your OS, which might not be quite as easy to read as searching your rpms. An example from my laptop:

uname -a
Linux Fedora1530 2.6.35.14-106.fc14.i686.PAE #1 SMP Wed Nov 23 13:39:51 UTC 2011 i686 i686 i386 GNU/Linux

One thing to note from Scott of the Pack clan (Information Security Expert of Renowned): “one of the first things I do during an investigation is try to figure out what distro I’m looking at. I usually check out /etc/issue, /etc/*release*, the package name, and uname. Mostly just to figure out if they all agree.” Thanks Scott!

My original, ignoble method of finding my CentOS version was this:

cat /etc/redhat-release

However, some will contend that this method is not foolproof and that some RedHat based distributions change the release file’s name. A more robust method is as follows:

cat /etc/*release*



19MAR
13
Tweet

View All Users Who Have Ever Logged Into Your Linux Server

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

Previously, I explored how to view all the users that are currently logged into my Linux server. A natural extension to that desire is to see all users who have logged into the server in the past. While current users are kept track of with the utmp file, past logins and logouts are kept track of in the wtmp/wtmpx file.

One way is to use the `last` command. My regular work laptop’s `last` output is rather boring:

wesley pts/7 :0.0 Wed Feb 15 19:57 - 20:42 (00:44)
wesley pts/6 :0.0 Tue Feb 14 20:53 - 21:18 (00:25)
wesley pts/5 :0.0 Tue Feb 14 20:46 still logged in
wesley pts/4 :0.0 Tue Feb 14 17:02 - 20:46 (03:43)
wesley pts/3 :0.0 Tue Feb 14 16:34 still logged in
wesley pts/2 :0.0 Tue Feb 14 16:25 - 16:26 (00:01)
wesley pts/1 :0.0 Tue Feb 14 16:24 still logged in
wesley tty1 :0 Tue Feb 14 12:28 still logged in
reboot system boot 2.6.35.14-97.fc1 Tue Feb 14 12:27 - 22:41 (1+10:14)
wesley tty1 :0 Tue Feb 14 09:19 - down (00:58)

If there is a specific user that you’d like to hone in on, use last [username] thusly:

# last root
root     pts/0        [ip removed]. Tue Feb 14 18:22   still logged in
root     pts/0        [ip removed]. Sun Feb 12 00:42 - 01:50  (01:07)
root     pts/0        [ip removed]. Sat Feb 11 16:24 - 19:41  (03:17)
root     pts/0        [ip removed]. Sat Feb 11 16:21 - 16:23  (00:02)

A useful switch when trying to hone in on remote logins is the -a switch which appends hostnames to the end of the table. -d will do a reverse lookup on remote IP addresses as well. A useful way to use this would be to see from which IP addresses and hosts a certain user account accesses your server. In my case, I know that only two people should theoretically have access to a certain FTP address. If I see that user account logging in from IP blocks in Namibia, I should probably be worred.

Another place to look for past logins is in /var/log/secure log files. They will also show failed login attempts. You could perform the following to find certain strings that show whatever events you’re interested in:

cat secure* | grep Accepted

However you will be in peril of winning a “Useless Use of Cat Award“.

A similar but different command is `lastlog` that by default prints out each user account that is on your machine along with the the account’s last login time.

someuser@someserver [/]# lastlog
Username Port From Latest
someuser pts/0 [ip removed]. Tue Feb 14 18:22:32 -0500 2012
bin **Never logged in**
daemon **Never logged in**
adm **Never logged in**
lp **Never logged in**

Lastlog itself merely scrys into /var/log/lastlog. You can modify the date from which it looks back to see when the last login occurred.

As a bonus, try `lastb` to see all the failed login attempts on your machine. Prepare to weep.

How do you figure out who was logged into your server and when? What better tools do you know of? I know none of the above are truly audit-level methods. Let me know in the comments below.



5MAR
2
Tweet

View All Users Who Are Currently Logged Into Your Linux Server

Posted in: SysAdmin
  |  by: Wesley David
Tags: Linux

While working on a Linux machine, you will very likely have a “What the heck just happened and who the heck just did it?” moment. This is when you’ll want to quickly see who’s currently logged in.

Before you go any further, you should acquaint yourself with the concept of a utmp file (possibly also known as the utmpx file). A utmp file keeps track of currently logged on users and is what any command will ultimately reference to bring you the desired information.

Firstly, you can try the `users` command. However, the information garnered is pretty sparing. It’s merely a username repeated as many times as there is a login session for it. In my case, on my laptop at the very moment I write this, I see this:

[wesley@Fedora1530 ~]$ users
wesley wesley wesley wesley

Two other tools that will give you vastly more information are `w` and `who`. Running `w` on the same laptop and sesson as I did `users` above, I get this output:

USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
wesley tty1 :0 Tue12 39:54m 1:34m 0.06s pam: gdm-password
wesley pts/1 :0.0 Tue16 1:38m 0.45s 0.44s ssh user@remoteserver1.com
wesley pts/3 :0.0 Tue16 1:38m 0.49s 0.47s ssh user@remoteserver2.com
wesley pts/5 :0.0 Tue20 0.00s 0.25s 0.03s w

That is considerably more information. The default output of `who` looks like this:

wesley   tty1         2012-02-14 12:28 (:0)
wesley   pts/1        2012-02-14 16:24 (:0.0)
wesley   pts/3        2012-02-14 16:34 (:0.0)
wesley   pts/5        2012-02-14 20:46 (:0.0)

`Who` defaults to simply showing the Name, Line, Time and Comment columns (at least my version on Fedora 14) however many other bits of information can also be added. Check the appropriate man pages.

Once you know who is logged in, whether or not you then harass them with ‘write‘ or pkill everyone who isn’t you is completely up to your discretion.

How do you like to figure out who is logged into your machine? Any pro tips?



1MAR
2
Tweet
Page 1 of 3 123

Advertisements

View All Users Who Are Currently Logged Into Your Linux Server
View All Users Who Are Currently Logged Into Your Linux Server
View All Users Who Are Currently Logged Into Your Linux Server
View All Users Who Are Currently Logged Into Your Linux Server

Follow This Blog

Want to have these posts emailed to you? Enter your email address here. Google Feedburner takes care of the rest!

Delivered by FeedBurner

About Me!

Contact Me!

The Nubby Archives

  • [-] 2012 (43)
    • May (7)
    • Apr (11)
    • Mar (10)
    • Feb (8)
    • Jan (7)
  • [+] 2011 (73)
    • Dec (4)
    • Nov (7)
    • Oct (6)
    • Sep (11)
    • Aug (9)
    • Jul (6)
    • Jun (3)
    • May (1)
    • Apr (8)
    • Mar (5)
    • Feb (5)
    • Jan (8)
  • [+] 2010 (71)
    • Dec (6)
    • Nov (3)
    • Oct (4)
    • Sep (14)
    • Aug (2)
    • Jul (4)
    • Jun (14)
    • May (19)
    • Apr (5)

Be Social!

Circle me!





profile for WesleyDavid on Stack Exchange, a network of free, community-driven Q&A sites

Copyright © 2011
Top