Showing posts with label group. Show all posts
Showing posts with label group. Show all posts

Tuesday, May 26, 2009

Controlling Group Access To Directories Recursively And Automatically Using Simple FACL's On Linux

Hey there,

Today we're going to take a look at using simple FACL's (file access control lists) to allow additional access restrictions (for one or more groups other than the directory owner's group) to a directory, while ensuring that the change propagates automatically to all subdirectories and files within all or any. Our examples for today should work on most distro's of Linux (and most proprietary Unix distro's), although the actual commands needed may be different ("man getfacl" or "man setfacl" should sort you out). For today's examples, all commands were run on RedHat Enterprise Server 5.2 (Tikanga - A Mãori word idiomatically meaning "The Mãori Way" or, more sanctimoniously, "correct," "right" or "true" - all absolutes ;)

The situation for today's example is pretty simple, although highly useful (of course, those aren't necessarily opposites ;). You have a directory that is owned by the user "user1" and the group "group1." A user name "user2", in the group "group2" needs to have access to your directory and also needs to be able to add new directories and/or files within that directory. To top it off, when either "user1" or "user2" creates a file or directory within the directory to be shared, that directory and/or file must be accessible to both "user1" and "user2" and owned by the group "group1." Simple enough :)

Of course, the easiest way to do this would be to add "user2" to "group1" and be done with it. However, since that might possibly afford "user2" more privilege than is actually needed (he/she may be able to access other files/directories that are owned by "group1"), a more restrictive solution is required. This is where simple FACL's come into play.

First, we'll take a quick look at the directory in question, with ls -l:

host # ls -ld shared_dir
drwxrwx--- 2 user1 group1 512 May 25 13:24 shared_dir


Once we're done, it will look almost exactly the same, except for the "+" symbol at the end of the alpha permissions display (This is an additional field, as opposed to setuid, setgid and sticky bit which replace the final alpha permissions field with a substitute character) As a point of note; some distributions include the "+" symbol at the end of "every" file, since all files/directories (on a filesystem that supports FACL's) have a default FACL. This seem counter-intuitive to me, since it makes it harder to eyeball which files/directories you've mucked with on purpose ;)

host # ls -ld shared_dir
drwxrwx---+ 2 user1 group1 512 May 25 13:24 shared_dir


Now, in order to make the whole concept of FACL's more accessible, it should be noted (at least, these days) that "all" files have FACL's (see slight caveat above), even if you don't explicitly set them. These FACL's mirror the existing file/directory permissions by default and you'll only the see the "+" symbol on files/directories where the default FACL has been modified (which is what we're going to do).

For instance, the FACL for our original shared_dir, looks like this before we even do anything, and can be obtained with the "getfacl" command (consider owner: user1, group:group1 and permissions of 770 - or drwxrwx---):

host # getfacl shared_dir
# file: shared_dir
# owner: user1
# group: group1

user::rwx
group::rwx
mask::rwx
other::---


All pound (#) comments are not acted upon, just like in most scripting languages. You can remove them, but they'll get automatically recreated every time you run a FACL command.

So, for this directory, we want to allow the group "group2" recursive read, write and execute permissions (read permissions, so they can see the contents of the directory or read any files in it, write permissions, so they can create new files/directories within the directory and/or write to files in it, and execute permissions, so that they can cd into the directory and/or execute files within it)

Luckily for us, this is actually fairly simple. All we need to do is to make use of the "setfacl" command.

host # setfacl -m g:group2:rwx shared_dir


This will change the FACL settings for the shared_dir directory, but won't do "exactly" what we want:

host # getfacl shared_dir
# file: shared_dir
# owner: user1
# group: group1

user::rwx
group::rwx
group:group2:rwx
mask::rwx
other::---


While doing this will allow "group2" read, write and execute access to the directory "shared_dir", the extended access will begin and end with the "shared_dir" directory, and any files/directories created by any user in "group2" will still be owned by "group2" when they are written to this directory.

If we want to satisfy the one remaining requirement (allowing "group2" to create new files/directories within "shared_dir" and have them all belong to "group1", with the unique FACL applied to each and every one), we need to set "default FACL's". Again, this is very simply done, and very easy to manage using the setfacl command Our first command will be to remove the rule we added with our last command. Then we'll set default FACL's for everyone and for the specific users and groups:

host # setfacl -x g:group2:rwx shared_dir
host # setfacl -d -m u:user1:rwx shared_dir
host # setfacl -d -m g:group1:rwx shared_dir
host # setfacl -d -m u:user2:rwx shared_dir
host # setfacl -d -m g:group2:rwx shared_dir


If you use the form above (which is, admittedly, more strict than it needs be; but I'm a control freak ;) and don't see the extra "default" FACL entries for the default user and group that own the file/directory, you can set those like this (also using setfacl):

host # setfacl -m d:u:rwx shared_dir
host # setfacl -m d:g:rwx shared_dir
host # setfacl -m d:o:--- shared_dir


These three entries should be put into your new FACL for the shared_dir by default, when you type the highly-specific FACL commands above, but if they're not, you'll want to add them. They are the key to propagating correct permissions on all new files/directories created within that directory.

Now typing "getfacl" should show you a dramatically different output:

host # getfacl shared_dir
# file: shared_dir
# owner: user1
# group: group1

user::rwx
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:user1:rwx
default:user:user2:rwx
default:group::rwx
default:group:group1:rwx
default:group:group2:rwx
default:mask::rwx
default:other::---


As I mentioned, you could leave out all the commands pertaining to the original owner (and group) of the file, but I like to be as specific as possible, just in case. Now, any file/directory that either user1, user2, or members of group1 or group2 create in this directory will have 770 permissions (rwxrwx---+) and their group will be set to "group1." You can also easily tell that your settings have worked by looking for the "+" symbol at the end of newly created files, which indicates that the FACL has been applied to your new file (although with a slightly different output for files than for directories):

host # who am i
user2
host # touch shared_dir/test
host # ls -l shared_dir
total 0
drwxrwx---+ 2 user2 group1 96 May 1 14:01 test

host # getfacl shared_dir/test
# file: test
# owner: user2
# group: group1

user::rw-
user:user1:rwx
user:user2:rwx
group::rwx
group:group1:rwx
group:group2:rwx
mask::rwx
other::---


And that's that :) If you still don't get the group propagation that you're expecting, it may not be supported on your OS. In that case, you can add this additional command (on top of the FACL's) to ensure that the correct group "sticks":

host # chmod g+s shared_dir


And you should be all set :)

Cheers,

, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Tuesday, April 21, 2009

Simple Script To List Groups In Passwd File Output On Linux And Unix

Hey There,

Today's simple, but somewhat useful, little Bash Script is brought to you by "The Human Fund: Money For People" ;) That was shamelessly lifted from "Seinfeld," but I always liked that fake name better than UNICEF ;)

Basically, todays Bash script manipulates the output of a simple "cat" of the /etc/passwd file and interpolates primary and secondary group values, for each user, into their respective output lines. It should run equally well on virtually any Linux or Unix distro since the passwd fields are in the same order on almost all of them and it doesn't make use of any of the group file fields past the fourth (so extended group files shouldn't affect this).

NOTE: This script goes well with this bash one liner to generate somewhat fancy w output. Haven't had your fill of pap for the day? Check that out ;)

The output you'll get from the script is similar to a simple "cat" of the /etc/password file (senility awareness kicking in - I just mentioned that ;), except that the fourth field will be modified. When you run this script, you'll notice that the fourth field of colon-delimited output includes alpha dash (-) delimited output of the form: pg=XXXX-sg=XXXX, rather than just the standard numeric Primary Group ID. The "pg" stands for Primary Group and the "sg" stands for Secondary Group. The Secondary Group, it should be noted, may contain more than one entry (split by commas), if the user belongs to more than one secondary group, and will print "NONE" if the user ID being listed doesn't belong to any groups other than its primary.

The script's simple to to run (because it doesn't have any fancy options ;) and should work fairly quickly (although, like everything, it could probably be more efficient. Once I fully develop my insect-like ability to differentiate microseconds, this sort of thing will bother me much more ;).

To run it, simply run it, like so, and you'll get your output (This is from a stripped Solaris box with only one user account and several useless standard accounts removed):

host # ./pwgroups
root:x:0:pg=root-sg=root,other,bin,sys,adm,uucp,mail,tty,lp,nuucp,daemon:Super-User:/:/sbin/sh
daemon:x:1:pg=other-sg=bin,adm,daemon::/:
bin:x:2:pg=bin-sg=bin,sys::/usr/bin:
sys:x:3:pg=sys-sg=sys::/:
adm:x:4:pg=adm-sg=sys,adm,tty,lp:Admin:/var/adm:
lp:x:71:pg=lp-sg=lp:Line Printer Admin:/usr/spool/lp:
uucp:x:5:pg=uucp-sg=uucp:uucp Admin:/usr/lib/uucp:
nuucp:x:9:pg=nuucp-sg=nuucp:uucp Admin:/var/spool/uucppublic:/usr/lib/uucp/uucico
smmsp:x:25:pg=smmsp-sg=smmsp:SendMail Message Submission Program:/:
listen:x:37:pg=adm-sg=NONE:Network Admin:/usr/net/nls:
webservd:x:80:pg=webservd-sg=webservd:WebServer Reserved UID:/:
postgres:x:90:pg=postgres-sg=postgres:PostgreSQL Reserved UID:/:/usr/bin/pfksh
nobody:x:60001:pg=nobody-sg=nobody:NFS Anonymous Access User:/:
noaccess:x:60002:pg=noaccess-sg=noaccess:No Access User:/:
nobody4:x:65534:pg=nogroup-sg=NONE:SunOS 4.x NFS Anonymous Access User:/:
user1:x:37527:pg=unixteam-sg=guys,folks:Captain Beefmeat:/export/home/user1:/bin/bash


Sure, this script won't save lives (or even change any ;) but I have found use for it from time to time. ...Which stands to reason, I suppose. If I don't think I'm ever going to do something again, I almost never script it out ;)

Hope you find it useful or, at least, mildly amusing :)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/bin/bash

#
# pwgroups - add alpha primary and secondary group information to /etc/passwd output
#
# 2009 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

export IFS=":"
while read one two three four five six seven
do
pri=$(grep -w ${four} /etc/group|awk -F":" '{print $1}')
sec=$(echo `grep -w ${one} /etc/group|awk -F":" '{print $1}'`|xargs echo|sed 's/ /,/g')
if [[ ${#sec} -eq 0 ]]
then
sec=NONE
fi
echo "${one}:${two}:${three}:pg=${pri}-sg=${sec}:${five}:${six}:${seven}"
done </etc/passwd



, Mike




Discover the Free Ebook that shows you how to make 100% commissions on ClickBank!



Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Friday, November 21, 2008

Another Simple Scriptlet To Make The Unix And Linux CLI More User Friendly

Hey there,

Today we're going to shoot out another quick scriptlet that might be useful (or distracting ;) from time to time. It’s a bit of a follow up on our post from earlier this week on using bash to produce fancy user names for folks logged into your machine, although it’s a little bit longer. Once again, if you go by the 65 character rule, this isn’t a one liner, even though it’s all going on one line ;)

Our little foray into variable interpolation today has to do with making /etc/passwd just a bit more accessible. Most folks are familiar with the 7 colon-separated fields of this file (if not, they’re: The user’s Username, an encrypted password (or usually an “x” if you’re using a shadow password system), the user’s UID, the user’s GID, the user’s gecos information (Also referred to as the “comment field,” usually either empty or populated with a short description to make the account more easily recognizable) , the user’s home directory and, finally, the user’s default shell)

Now, say what you will about the structure and setup of the passwd file, but it’s fairly easy to follow. Almost everything in it is the opposite of cryptic. The password field (field number 2) is, of course, not going to be tailored for your ease of understanding ;) If you get really lucky and you hop on a machine that actually lists the encrypted password in field two of /etc/passwd, you can copy the file to any remote machine and go to work on it. We've posted quite a few scripts to do automated password cracking. You should just see an "x" for a standard user account. If you don’t, have a talk with your SysAdmin or, if you’re him, please move on to a shadowed password system. Too much information exists in the public domain to make the old-style setup anything more than a trifling hassle to someone who wants to exploit your system. Especially a disgruntled employee!

Other than that, the user ID (field number 3) is an easy relation to make, since the username is in the same file (field number 1). The only thing in there that doesn’t practically explain itself is field number 4; the GID (group id) field. It’s not that big of a deal to look a user up in /etc/passwd, glean that group id information and find out what group the user is in by looking at /etc/group. It’s as simple as this:

host # grep user1 /etc/passwd
user1:x:37527:501::/export/home/user1:/bin/bash
host # grep 501 /etc/group
people::501:


and, just like that, we know that the user "user1"'s primary group membership is in the group "people." There are also secondary groups to consider, but finding this out is trivial as well. Just do the following:

host # grep -w user1 /etc/group
guys::600:user1
folks::601:user1


And, yes, I can hear you out there ;) I'm aware of commands like "groups" and "id" ;) They're very good at getting this information, as well (which is why we're going to use "groups" in our one-long-liner. Your output may look slightly different). Note that some versions don't have the -a option for "id" and some have either -g, -G, any combination of the three or all of them - it depends on your distro:

host # groups <-- This is supposed to list groups in order, from left to right, with the leftmost group being the "primary" and every group after that being a "secondary." The ordering of the "secondary" groups in the list is generally "as they appear" in /etc/group. So, since the line with "guys" is on a line closer to the beginning of the /etc/group file than the line with "folks," they're printed in that order. No other relationship exists between them that I'm aware of.
people guys folks
host # id -a
uid=37527(user1) gid=501(people) groups=501(people)
<-- On Solaris; not quite as helpful as "id" on other flavours of Linux or Unix.

Anyway, I think I've met my word-count quota ;) Just kidding. I have no idea how much I've typed. I'm not even sure I want to know...

Here's a nice little command line (and, consequently, the topic of this post ;) to print every user's group(s) in the (modified) output of /etc/passwd. Just type it out, like so:

host # IFSBAK=$IFS;export IFS=":";while read one two three four five;do groupnames=`groups $one|sed 's/ /,/g'`;echo "${one}:${two}:${three}:${groupnames}:${five}";done </etc/passwd;export IFS=$IFSBAK


...lots of output left out for reasons of brevity and security :) ...
noaccess:x:60002:noaccess:No Access User:/
user1:x:37527:people,guys,folks::/export/home/user1:/bin/bash
...


And, there we have it. All nice and tidy :) Here's the same thing in script format (below) to make it a little easier to read. Be sure (now matter how you run it) that you don't clip the beginning and end, as you'll probably want to reset your shell's IFS (field separator) to what it was before we changed it to the colon (:) to make parsing /etc/password possible without using awk or cut, etc... Also, if it's of any interest and you noted that I only counted my variables up to "five" it's because "while read" will swallow up the rest of a line in its last variable. So, instead of reading and writing five, six and seven, I just read five, since that would include from field five all the way to the end of the line (at the end of field 7), and field 4 (the group field) was the last field on every line that we were actually interested in :)

#!/bin/bash

IFSBAK=$IFS
export IFS=":"

while read one two three four five
do
groupnames=`groups $one|sed 's/ /,/g'`
echo "${one}:${two}:${three}:${groupnames}:${five}"
done </etc/passwd

export IFS=$IFSBAK


Have a great weekend!

, Mike




Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Tuesday, September 30, 2008

How To Resolve Veritas Disk Group Cluster Volume Management Problems On Linux or Unix

Hey There,

Today we're going to look at an issue that, while it doesn't happen all that often, happens just enough to make it post-worthy. I've only seen it a few times in my "career," but I don't always have access to the fancy software, so this problem may be more widespread than I've been lead to believe ;) The issue we'll deal with today is: What do you do when disk groups, within a cluster, conflict with one another? Or, more correctly, what do you do when disk groups within a cluster conflict with one another even though all the disk is being shared by every node in the cluster? If that still doesn't make sense (and I'm not judging "you," it just doesn't sound right to me, yet ;) what do you do in a situation where every node in a cluster shares a common disk group and, for some bizarre reason, this creates a conflict between nodes in the cluster and some of them refuse to use the disk even though it's supposed to be accessible through every single node? Enough questions... ;)

Check out these links for a smattering of other posts we've done on dealing with Veritas Volume Manager and fussing with Veritas Cluster Server. Some of the material covered may be useful if you have problems with any of the concepts glossed over in the problem resolution at the end.

Like I mentioned, this "does" happen from time to time, and not for the reasons you might generally suspect (like one node having a lock on the disk group and refusing to share, etc). In fact, the reason this happens sometimes (in this very particular case) is quite interesting. Even quite disturbing, since you'd expect that this shouldn't be able to happen.

Here's the setup, and another reason this problem seems kind of confusing. A disk group (we'll call it DiskGroupDG1 because we're all about creativity over here ;) is being shared between 2 nodes in a 2 node cluster. Both nodes have Veritas Cluster Server (VCS) set up correctly and no other problems with Veritas exist. If the DiskGroupDG1 disk group is imported on Node1, using the Cluster Volume Manager (CVM), it can be mounted and accessed by Node2 without any issues. However, if DiskGroupDG1 is imported on Node2, using CVM, it cannot be mounted and/or access by Node1.

All things being equal, this doesn't readily make much sense. There are no disparities between the nodes (insofar as the Veritas Cluster and Volume Management setup are concerned) and things should be just peachy going one way or the other. So, what's the deal, then?

The problem, actually, has very little to do with VCS and/or CVM (Although they're totally relevant and deserve to be in the title of the post -- standard disclaimer ;). The actual issue has to do, mostly, with minor disk numbering on the Node1 and Node2 servers. What???

Here's what happens:
In the first scenario (where everything's hunky and most everything's dorey) the DiskGroupDG1 disk group is imported by CVM on Node1 and Node1 notices that the "minor numbers" of the disks in the disk group are exactly the same as the "minor numbers" on disk it already has mounted locally. You can always tell a disk's (or any other device's) minor number by using the ls command on Linux or Unix, like so:

host # /dev/dsk # ls -ls c0t0d0s0
2 lrwxrwxrwx 1 root root 41 May 11 2001 c0t0d0s0 -> ../../devices/pci@1f,4000/scsi@3/sd@0,0:a
host # /dev/dsk # ls -ls ../../devices/pci@1f,4000/scsi@3/sd@0,0:a
0 brw-r----- 1 root sys 32, 0 May 11 2001 ../../devices/pci@1f,4000/scsi@3/sd@0,0:a
<-- In this instance, the device's "major number" is 32 and the device's "minor number" is 0. Generally, with virtual disks, etc, you won't see numbers that low.

Now, on Node1, since it recognizes this conflict on import, does what Veritas VM naturally does to avoid conflict; it renumbers the imported volumes ("minor number" only) so that the imported volumes won't conflict with volumes in another disk group that's already resident on the system it's managing. Therefore, when Node2 attempts to mount, with CVM, the command is successful.
In the second scenario (where thing are a little bit hunky, but not at all dorey), Node2 imports the DiskGroupDG1 disk group and none of the minor numbers in that disk group's volumes conflict with any of its local (or already mounted) disk. The disk group volumes are imported with no error, but, the "minor numbers" are not temporarily changed, either. You see where this is going. It's a freakin' train wreck waiting to happen ;)

Now, when Node1 attempts to mount, it determines there's a conflict, but can't renumber the "minor numbers" on the disk group's volumes (since they're already imported and mounted on Node2) and, therefore, takes the only other course of action it can think of and bails completely.

So, how do you get around this for once and all time? Well, I'm not sure it's entirely possible to anticipate this problem with a variable number of nodes in a cluster, all with independent disk groups and, also, sharing volume groups between nodes, although you could take simple measures to prevent it most of the time (like running ls against every volume in every disk group in a cluster every now and again and making sure no conflicts existed. The script should be pretty easy to whip up).
Basically, in this instance (and any like it), the solution involves doing what Veritas VM did in the first scenario; except doing it all-the-way. No temporary-changing of "minor numbers." For our purposes, we'd like to change them permanently, so that they never conflict again! It can be done in a few simple steps.

1. Stop VCS on the problem node first.

2. Stop any applications using the local disk group whose "minor numbers" conflict with the "minor numbers" of the volumes in DiskGroupDG1.

3. Unmount (umount) the filesystems and deport the affected disk group.

4. Now, pick a new "minor number" that won't conflict with the DiskGroupDG1 "minor numbers." Higher is generally better, but I'd check the minor numbers on all the devices in my device tree just to be sure.

5. Run the following command against your local disk group (named, aptly, LocalDG1 ;) :

host # vxdg reminor LocalDG1 3900 <-- Note that this number is the base, so every volume, past the initial, within the disk group will have a "minor number" one integer higher than the last (3900, 3901, etc)

6. Reimport the LocalDG1 disk group

7. Remount your filesystems, restart your applications and restart VCS on the affected node.

8. You don't have to, but I'd do the same thing on all the nodes, if I had a window in which to do it.

And, that would be that. Problem solved.

You may never ever see this issue in your lifetime. But, if you do, hopefully, this page (or one like it) will still be cyber-flotsam on the info-sea ;)

Cheers,

, Mike




Please note that this blog accepts comments via email only. See our Mission And Policy Statement for further details.

Thursday, June 26, 2008

Mirroring Your Boot Disk Using Veritas On Sun Without Encapsulation

Hey There,

Today, we're going to take a look at a using Veritas to mirror your boot disks, without using encapsulation. There's raging debate about whether or not Veritas root disk encapsulation is bad (some folks are great with it because it takes care of everything, while some folks hate it because it's very hard to deal with when it doesn't take care of everything ;)

The following procedure was introduced quite a while ago by a pair of gentleman named Gene Trantham and John S. Howard in an article they wrote for Sun Blueprints Online (A site run by Sun that highlights best-practices for many, many things Solaris). I believe it's now simply referred to as the "Trantham/Howard Method."

Although I've used this method many times in my career, there's no point in re-writing the instructions (although I did, to a certain degree, to make them more concise and accessible). I did, however, want to have this information included on my blog, to complement (and complete) our earlier posts on patching your Veritas root disk, Veritas Volume Group setup, etc. The full document can be read here in the August 2000 Online Edition of Sun Blueprints.

So, without further ado, and, hopefully you'll find this helpful as well, the "Trantham/Howard Method" for mirroring boot disks using Veritas on Sun Solaris (somewhat modified and truncated):

Enjoy,

1. Install the basic Veritas Volume Manager Software.

2. Install any required Veritas licenses.

3. Use vxinstall to encapsulate the root disk c0t0d0 (Or whatever cxtxdx disk name accurately reflects your setup). Choose not to encapsulate the root disk and don't mirror it. For this post's sake, name it rootdisk Once the root disk is encapsulated, simply reboot and check "vxprint -ht" - You should note that only your rootdisk (and its Veritas name) is listed out.

4. Initialize the root mirror disk c0t1d0 (again, substitute with your own specific controller-target-disk name).

host # /usr/lib/vxvm/bin/vxdisksetup -i c0t1d0
host # vxdg adddisk rootmirror=c0t1d0


5. Manually attach the mirror plexes to the root volumes with "vxrootmir" (manually mirror the swapvol, usr and var volumes, if necessary, as well):

host # /usr/lib/vxvm/bin/vxrootmir rootmirror
host # vxassist mirror swapvol alloc=rootmirror
host # vxassist mirror usr alloc=rootmirror
host # vxassist mirror var alloc=rootmirror


While you wait for this to finish, you can check on the progress with the vxtask command.

6. Once your root disk is mirrored, disassociate the original plexes on c0t0d0, remove them, and remove the encapsulated rootdisk from the rootdg diskgroup:

host # vxplex dis rootvol-01 swapvol-01 var-01 usr-01
host # vxdg rmdisk rootdisk


Now your operating system is entirely running off of the c0t1d0 disk.
At this point, the operating system is based just on the initialized disk c0t1d0, which you can see by looking at the output of "vxprint -ht" again.

7. Now initialize, as opposed to encapsulating, c0t0d0:

host # /usr/lib/vxvm/bin/vxdisksetup -i c0t0d0
host # vxdg adddisk rootdisk=c0t0d0


8. Now, mirror everything from the rootmirror disk back to the rootdisk:

host # /usr/lib/vxvm/bin/vxrootmir rootdisk
host # vxassist mirror swapvol alloc=rootdisk
host # vxassist mirror var alloc=rootdisk
host # vxassist mirror usr alloc=rootdisk


Again, you can use the vxtask command to view the progress of this command, which may take some time to complete. Also, this process removes the "rootdisk-B0" subdisk. This is used by Veritas to protect the boot block, but isn't necessary when you're not encapsulating your disks.

9. Using the output of "vxprint -ht", create disk slices corresponding to the Veritas subdisks. The usage for vxmksdpart command is:

vxmksdpart [-f] [-g diskgroup] subdisk sliceno [tag flags]

You won't need to run through this for the root slice since vxrootmir has already done this for you. You will need to do this for the other slices, though. But, don't use vxmksdpart just yet.

10. On the "new" root disk, first create the slices for the partitions you're going to mirror:

host # /usr/lib/vxvm/bin/vxmksdpart rootdisk-02 1 0x03 0x01
host # /usr/lib/vxvm/bin/vxmksdpart rootmirror-02 1 0x03 0x01


and so on for each required partition (again, you can get this output from "vxprint -ht"). The "sliceno" part of the command syntax is very important here!

host # /usr/lib/vxvm/bin/vxmksdpart rootdisk-03 5 0x07 0x00
host # /usr/lib/vxvm/bin/vxmksdpart rootmirror-03 5 0x07 0x00
...


11. Among other things (like backing up /etc/vfstab, etc) be sure to capture the current disk partition information for both disks, before rebooting, using vxprtvtoc:

host # /usr/lib/vxvm/bin/vxprtvtoc -f /tmp/disk1 /dev/rdsk/c0t0d0s2
host # /usr/lib/vxvm/bin/vxprtvtoc -f /tmp/disk2 /dev/rdsk/c0t1d0s2
host # cat /tmp/disk1 /tmp/disk2 > /etc/vtoc


12. Update your system dump configuration to use the swap partition on the primary disk:

host # dumpadm -d /dev/dsk/c0t0d0s1
Dump content: kernel pages
Dump device: /dev/dsk/c0t0d0s1 (swap)
Savecore directory: /var/crash/host
Savecore enabled: yes


13. In the OBP, be sure to setup both disks using devalias (name them disk and rootdisk, if you want, or whatever makes the most sense to you) and set your configuration to have the boot-device set up to make it easy for your system to fail over if the primary disk goes bad:

ok> setenv boot-device disk, rootdisk, net

14. Be sure to test booting from the OBP for both disk and rootdisk. Assuming that goes well, you're all set :)

, Mike

Saturday, June 21, 2008

Security Basics For Linux and Unix Installations - Part 2

Hey there,

Following up on our first two posts on basic Linux and Unix installation security and even more installation security measures, we're going to move on to the next section. Today, we'll be focusing more specifically on user, and group, accounts, and modifications that we want to make in that arena.

Again, this series of posts is based mostly on Solaris Unix and RedHat Linux, so it can't possibly apply to everything. I welcome any comments regarding it, especially as they pertain to additional security and other Operating Systems. Just to be clear, also, we won't be touching on more advanced stuff like setting up firewalls, etc. The summary of this 5-part post should end up being a bullet list that you can run through and take care of without having to go too crazy ;)

And, of course, my suggestion, to everyone who has the rights and means, is to script out as much of this method as possible. However you end up securifying your system, once you have your routine down, having Jumpstart or Kickstart do it for you from then on out is much less of a hassle (usually :)

See you tomorrow for section 3!

Cheers,

OS Installation Guidelines, Part 2: Users and Accounts

1. Add accounts for all necessary users. Require valid reasons for all accounts created.

2. You can ignore this step if you're using Solaris or RedHat's OpenSSH pkg or rpm, since it will be complete already: Be sure to add a user account for sshd. This will be required for our OpenSSH to run correctly. Should be as simple as

host # useradd –m –d /users/sshd sshd
host # passwd –l sshd
<--- (The passwd –l just locks the password so no one can login to the account. This is okay, since the sshd account is only necessary for privilege separation.

IMPORTANT NOTE FOR POINTS 3 THROUGH 6 REGARDING USER REMOVAL: Please note that for point three, we specify "userdel -r," because these users have home directories that are NOT "/" - If there is any doubt in your mind that an account you want to remove has the root filesystem as its home directory, use "userdel" without the -r, as use of that flag may effectively destroy your system. An easy way to find out what a user's home directory is involves simply grepping the username out of /etc/passwd and checking out the second to last field.

3. userdel –r lp, uucp, nuucp, some, all or more if possible (the nobody account should be removed, too, unless it’s used by a web server or some other application). Note that your list will be larger on RedHat since they generally have a user for every service and you should remove every user for every service you're not using if it wasn't removed by rpm -e. Also, on Redhat, be sure to check for matching entries for the user in /etc/group

4. userdel nobody (This should not be removed if it’s used by a web server or some other application)

5. userdel smtp (Non-existent in Solaris9).

6. userdel mail (Non-existent in Solaris9).

7. chmod 700 all user directories.

8. Comment out gsscred and nfsfind from root cron on Solaris. Delete sys, lp, adm, root.au, uucp and all unnecessary crontabs, if possible.

9. Add “0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/lib/sa/sa1” and “59 23 * * * /usr/lib/sa/sa2 -b -g -r –u” to root's cron. On RedHat you'll need to have the sysstat RPM installed in order to use sar. If it "is" installed on Redhat, check out /etc/cron.d to make sure that it is being run in cron and modify the setup per above, to increase or decrease the number of times it runs, if you need to.

10. Create the directory /var/adm/sa (/var/log/sa on RedHat) if it doesn't exist, and chown it to root:yourAdministratorsGroup. Then chmod the directory to 660.

11. Add “/usr/lib/acct/ckpacct” to root's cron on Solaris, if the machine does not have high user activity and has adequate disk space for logging. Remove any other /usr/lib/acct lines in the Solaris root crontab. For RedHat users, make sure that you have the psacct RPM installed. The default settings should be okay and you can use chkconfig or ntsysv to ensure that process accounting is set to run at boot time.

12. Remove user directories for users who no longer have accounts on the machine.

13. Remove crontab entries in /usr/spool/cron/crontabs (Solaris) or /var/spool/cron (RedHat) for users that no longer have accounts on the machine.

14. Add empty .rhosts, .netrc and .exrc files in all user home directories.

15. chmod 0 and chown root all user .rhosts, .netrc and .exrc files.

16. userdel (–r, if their home directory isn’t "/" ) all users, aside from root, with uid 0.

17. Change the group for any user (other than root) that has a gid of 0, if possible.

18. Be sure to include a umask of 022 in any user’s .profile if their account will require their home directory to be somewhat publicly available. Examples of such an accounts include development or group-based accounts. These kind of accounts are used to ease the ability of a group to work together. Of course, the standard 027 umask would make this impossible. Please use discretion and do this only for accounts where the need is real.

19. For all generic accounts, make them su-only. You can find detailed instructions on how to do this, including some pitfalls and stumbling blocks you may encounter, in our post on making generic accounts su only. As luck would have it, it's still aptly named ;)

to be continued...

, Mike

Saturday, March 1, 2008

Volume Groups Setup With Veritas Volume Manager

Hey There,

Today we're going to set up volume groups using the disks, and disk groups, that we setup yesterday in our post on creating disk groups with Veritas Volume Manager.

Our assumptions for the disks, and disk groups, we've setup are also spelled out in that same post about initializing disks and creating those disk groups. If you have any questions regarding the setup we're working from, they should be answered there :)

Now, we're ready to take the disk groups we created yesterday (again, not recommended to have all 3 of those exist at one time in reality. But highly recommended for the purposes of explaining the basic commands and concepts in today's post ;)

We're going to create the 4 most basic types of volumes today. These are referred to by their RAID (Redundant Array of Indepedent Disks) numbers, which translate as follows:

RAID 0 = Striped/Concatenated disk <--- Use this if you just want to combine any number of disks into one giant volume. Stripes of data are written across multiple disks, but this only enhances usability and doesn't provide any protection from disaster if a disk in the volume group fails.

RAID 1 = Mirrored disk <--- Use this if you want to mirror your disk, so that you have a simple mirror to fail over to if your primary disk fails.

RAID 5 = Striped disk with parity <--- Use this if you want to make your volume group highly available and recoverable. You'll need at least 4 disks in your RAID 5 group for this setup to be worthwhile, but it can make uptime and recovery a lot less of a hassle if you've got the disk to throw at your storage needs.

RAID 1+0 = Concatenated Mirrored disk <--- (as opposed to Mirrored Concatenated disk). The distinction to be made here is that RAID 1+0 (Striped Mirrors) consists of several disk mirrors, each reflection of which is concatenated/striped to create a larger volume. In RAID 0+1 (Mirrored Stripes), you have a set of disks Concatenated/Striped first and then Mirrored back to an equal amount of concatenated disk. Hopefully, I'm explaining this well enough, and not over-explaining it ;) Basically, with RAID 1+0, you can afford to lose a lot more disk and remain "up" than you can with RAID 0+1 (In RAID 0+1, loss of any disk A on one side of the mirror and disk C on the other side will bring you down, since each loss of a single disk, on either side, takes down that whole Concatenated miror. RAID 0+1 is like creating a much larger simple Mirrored disk than you could create with RAID 1).

For the following examples, we're going to use the command "vxassist." While you can use vxmake, etc, to perform these same functions (and, eventually, may have to if you need to do things more precisely), using vxassist is optimal when you're working with fresh disk and want to get up and running quickly :)

1. Creating a RAID 0 Volume Group named volume_group1 (From disk_group2, which contains hdc, hdd, hde and hdf):

host # /usr/sbin/vxassist -g disk_group2 -b make volume_group1 768000s layout=striped stripeunit=128 ncolumn=4

2. Creating a RAID 1 Volume Group name volume_group2 (from disk_group1, which contains hda and hdb):

host # /usr/sbin/vxassist -g disk_group1 -b make volume_group2 512000s layout=nostripe,log nmirror=2

3. Creating a RAID 5 Volume Group name volume_group3 (from disk_group3, which contains all 6 disks):

host # /usr/sbin/vxassist -g disk_group3 -b make volume_group3 1280000 layout=raid5,log stripeunit=32 ncolumn=6

4. Creating a RAID 1+0 Volume Group name volume_group4 (from disk_group3, which contains all 6 disks):

host # /usr/sbin/vxassist -g disk_group3 -b make volume_group4 768000s layout=stripe-mirror,log nmirror=2 stripeunit=128 ncolumn=2

As a bit of explanation, for each instance of vxassist that we invoke, you'll notice some common elements:

The "-g" flag simply asks us to name the disk group that we'll be using to create the volume group.

The volume group name (after "-b make") is simply what we want to call the particular volume group we're creating.

The following field is the size of the volume in sectors.

The field after that is the "layout" that we're looking to create. For RAID 0, we chose "striped." For RAID 1, "nostripe, log." For RAID 5, "raid5, log." And, for RAID 1+0, "stripe-mirror,log."

The "stripeunit" is only required for striped volumes and you can leave this out if you want to accept your VVM version's default.

The final column is also variable. For RAID 0, 5 and 1+0 we have the "ncolumn" attribute which basically translates to the number of disks in our volume group. For RAID 1 and 1+0 we have the "nmirror" attribute which translates to how many mirror devices we want to have. Two mirrors is actually the minimum you can have and really means "one disk, mirrored to one other disk." I initially found that confusing. Assuming I'm not the only guy who wondered if I was triple-mirroring by specifying two mirrors, I thought I'd just add that on there ;)

Hopefully this has been helpful to you. I'll be writing more on this, Solaris Volume Manager and LVM for Linux in posts to come :)

Best Wishes,

, Mike




Friday, February 29, 2008

Setting Up Disk Groups In Veritas Volume Manager

Good day,

Today we're going to take a look at the very basics of getting started with Veritas Volume Manager. We're not going to limit ourselves to any specific operating system, as all of these commands work almost exactly the same on Unix and Linux. We'll be using RedHat disk identifiers, for brevity's sake, but it should be noted that wherever we list out a disk like "sda," you can substitute c0t0d0 (or what not) if you're using Solaris. Of course, if you're running RedHat, you're probably already using LVM, in which case VVM might not be worth the hefty asking price.

Tomorrow, we'll take a look at creating volumes with these disk groups , but for now, I thing we'll be chewing up sufficient HTML landscape just running down these basic commands ;) We'll be concentrating on the command line functionality in this small series of posts. You can do all of this stuff using the "vxdiskadm" command also, which is a tty gui that pretty much walks you through the steps very easily in plain English.

Our assumptions for today's exercise (and tomorrow's), are that you have 6 disks on your system of equal size, manufacturer, etc, and that you've already installed and (at least temporarily) licensed Veritas Volume Manager on the OS. Our only other obvious assumption will be that you may or may not have installed the Veritas File System. These commands should work equally well for vxfs, ufs, ext3, etc.

The first thing you'll want to do to set up your disk group(s) is to initialize all of your disks so that Volume Manager recognizes them. This is very simply done on the command line, like so, for our six disks (/dev/hda, /dev/hdb, /dev/hdc, /dev/hdd, /etc/hde, /dev/hdf):

host # /etc/vx/bin/vxdisksetup -if hda
host # /etc/vx/bin/vxdisksetup -if hdb
host # /etc/vx/bin/vxdisksetup -if hdc
host # /etc/vx/bin/vxdisksetup -if hdd
host # /etc/vx/bin/vxdisksetup -if hde
host # /etc/vx/bin/vxdisksetup -if hdf


Note: For all of these operations, you can check on the progress (if you run a command that takes a good while to complete) using the "vxtask" command!

It's generally good practice to include /etc/vx/bin in your PATH environment variable (even on Linux, for backward compatability's sake). At the very least, it will save your fingers from type-cramping ;)

The command line options we've added here, before the disk name declarations (which don't need to be fully qualified with /dev... ), are "-i" to initialize the disks (by writing a disk header instead of just creating a partition for VVM use) and "-f" to force the initialization (This is technically an option to the "vxdisk" command, but can be used with "vxdisksetup").

Now, to create your disk group, or groups, you just simply have to run the following. Let's say we want to create two disk groups (disk_group1 and disk_group2); the first with hda and hdb, and the second with the remaining disks we've initialized. We can take care of that by executing:

host # /usr/sbin/vxdg init disk_group1 disk_group1_01=hda disk_group1_2=hdb
host # /usr/sbin/vxdg init disk_group2 disk_group2_01=hdc disk_group2_2=hdd disk_group2_3=hde disk_group2_4=hdf


We'll also create a disk group , called disk_group3, consisting of all 6 disks (Of course, it's not recommended to have any single Veritas disk belong to more than one disk group, but we're going to do it here, just so we have a disk group that we can use in tomorrow's examples on setting up volume groups).

hosts # /usr/sbin/vxdg init disk_group3 disk_group3_01=hda disk_group3_2=hdb disk_group3_3=hdc disk_group3_4=hdd disk_group3_5=hde disk_group3_6=hdf

And we're all set. Now all six of our disks are initialized for use with Veritas Volume Manager and we've got them ordered into disk groups.

Tomorrow, we'll take a look at creating different types of volumes from the disks, and disk groups, that we've set up today.

Until then,


, Mike




Saturday, December 8, 2007

Adding Storage using Volume Manager in a Veritas Cluster

Today, we're going to take a look at adding extra disk to a Veritas Cluster using Veritas Volume Manager. We'll assume for the purposes of this post, that you've been asked to add 35gb of space to a Veritas volume (filesystem: /veritas/a - volume name: veritas_a). Now we'll walk, step by step, through determining whether we have the disk available to add, and adding it if we do.

The first thing you'll want to do is determine what disk group(s) the filesystem/volume belongs to. Generally, you'll be told this when you're asked to add disk to an existing system, but we'll just assume the very worst ;) In any event, even if you are told, it's good practice to verify that the filesystem/volume does, in fact, belong to the disk group(s) the request is asking to have you augment.

Now, since we're dealing with a Veritas Cluster, if the disk group is shared between more than one server node, you can run:

vxdctl -c mode

and that will show you what the master node is. This server is where you'll want to execute all of your Veritas Volume Manager commands. If the cluster is inactive, vxdctl will tell you that, and you'll need to execute your commands on the server you're already on.

Now, either on the Cluster's master node, or the machine you're on if the cluster is inactive, get a list of all the disk groups, like so:

vxdg list
NAME STATE ID
rootdg enabled 1199919191.1025.host1
mydg enabled 8373777737.1314.host2


Since the user requested more filespace under /veritas/a, we'll need to see what disk group this filesystem/volume belongs to:

df -kl | grep veritas
/dev/vx/dsk/mydg/veritas_a 34598912 24632328 9903320 72% /veritas/a
/dev/vx/dsk/mydg/veritas_b 34598912 649112 33687984 2% /veritas/b
/dev/vx/dsk/mydg/veritas_c 35350080 17696 35056360 1% /veritas/c


We can see that, under /dev/vx/dsk, mydg is showing as the disk group for our /veritas/a filesystem, and veritas_a is showing as the volume. In cases like this, it's a time saver if you just set the default group once on the command line, so you don't have to use the "-g" option for every command you run:

vxdctl defaultdg mydg

Now you'll run some standard commands to make sure that your system can see all the disk available to it and make sure that the data is fresh:

devfsadm -Cv (note that the cluster will only update the volume manager configuration for cluster nodes that use the mydg diskgroup -- we don't have to specify that here, because we defined it as the default above)
vxdctl enable (this is basically the second part of the same update. The devfsadm command is Solaris specific while vxdctl is Veritas specific)

Now we need to check for free space, to see if we can accommodate the request with what we have available to us at present:

vxdg -g mydg list <-- Again "-g mydg" is optional because it's the default.
DISK DEVICE TAG OFFSET LENGTH FLAGS
DISK1 c5t27d27s2 c5t27d27 69198720 1501440 n
DISK2 c5t27d30s2 c5t27d30 69198720 1501440 n
DISK3 c5t27d28s2 c5t27d28 69198720 1501440 n


This output is, admittedly, a pain to read, because it expects you to be able to calculate disk offsets in your head. For this output, if the offset were zero and length was 70700160 and flags were '-' then that DISK would have 35 GB of free space available to us. Here all the listed storage has been partially used up. Hence, there is not enough storage space available!. We can also verify this by running

vxdg free (optionally: vxdg -g mydg free) to see if there is any free space left in the disk group. Either way, we're out of luck, it would seem.

So, now we're going to have to look into Veritas' disk configuration and see if there isn't a spare disk (hope) that we can pick up and import into the mydg diskgroup so that we can add the space (One thing to note in the output below is that all online disk shows its disk group membership even though it's imported locally):

vxdisk -o alldgs list <--- (abbreviated to keep this post bearable ;)
DEVICE TYPE DISK GROUP STATUS
c0t0d0s2 sliced - - error
c0t2d0s2 sliced disk02 rootdg online
c1t2d0s2 sliced disk01 rootdg online
c5t27d40s2 sliced - (mydg200) online
c5t27d41s2 sliced - (mydg2) online
c5t27d300s2 sliced - (mydg300) online
c5t20d99s2 sliced - - error


Luckily, it appears that disk c5t20d99s2 is available and doesn't belong to any existing disk groups! We'll use the command line to initialize this free disk and add it to our disk group (mydg):

vxdiskadd c5t20d99s2

You will be asked if you want to initialize the disk (or re-initialize it, if it's already initialized). Answer yes to either option, to keep things simple. Then it will ask you what disk group you would like to add the disk to. Answer: mydg. It will ask you if you want to use a default disk name. Depending on your situation, this may be okay, but we'll say no and add it as "DISK4" to keep with our naming standard. Then you will be prompted if you want to add the disk as a spare for the mydg disk group. Answer no to this, or you won't be able to use it for the additional storage you want! Answer no again, when it asks you if you want to encapsulate the disk, and then answer yes when it asks you if you want to initalize it. You can then choose to perform a surface analysis before adding it (It says it's highly recommended but my experience is it's generally not necessary and takes a very very very long time). Phew... that wasn't too much to info to have to feed to a single command ;)

Now, we'll want to grow the mydg disk group's volume and filesystem size. We've added the new disk, so we have more space, but the user can't see it or use it at this point. Now, common wisdom is to use the vxassist command. It's common, because it can be a great command to use (very simple), but I prefer to use "vxresize" because, unless your filesystem is vxfs, running vxassist to grow the volume (/veritas_a) can cause serious issues when growing the filesystem (if, for instance, you're using the Veritas Volume Manager but have your volume filesystem type set to Solaris "ufs")!

Calculate the maximum length of your new volume using vxassist (this part is okay - forget about what I just said above - that only applies to using vxassist to do the actually growing):

vxassist -g mydg (optional, if default is already set) maxsize <--- This will be the NEW_LENGTH argument for the next command.

vxresize -F (vxfs or ufs,usually) -g mydg (optional, still) -x (to make sure that the operation fails if the volume doesn't increase in length) veritas_a NEW_LENGTH <-- The last time I checked, - and another reason I prefer this method - this command grows your filesystem with the volume so you don't need to run any more steps after this.

Of course, you can keep tabs on all this, after you're done typing, using the vxtask command. At no point during this entire operation will you need to unmount your filesystem. I believe it's "recommended" (because something could always go wrong), but I've never found it to be necessary (technically, it's not supposed to fail, but Veritas has to cover itself, just in case)

Once the task is finished, your "df -k /veritas/a" output should show your new disk available and ready for use!

Cheers,

, Mike