1: #!/bin/bash
2: DB_USER='icinga'
3: DB_PASSWORD='Jaht5aChkib2The5iA'
4: SALT=$DB_USER
5: MD5_PASSWORD=$(echo -n ${DB_PASSWORD}${SALT} | md5sum | cut -d" " -f1)
6: PASSWORD_HASH="md5${MD5_PASSWORD}"
7: CURRENT_PASS=$(psql -tA -c "SELECT passwd FROM pg_shadow WHERE usename = '${DB_USER}';")
8:
9: if ! [ $CURRENT_PASS == $PASSWORD_HASH ]; then
10: psql -tA -c "ALTER ROLE ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';"
11: fi
Note: to be run locally as postgres user.
onsdag 6. juni 2012
Check for correct password in PostgreSQL
Check if a ROLE has the correct password, and change if it isn't:
mandag 3. januar 2011
Restrict ssh access to one command, but allow parameters
Sometimes one needs to allow a script to login to a server using a SSH key to do a job. That can be achieved by adding the scripts SSH public key to the remote user's authorized_keys file. The private keys are often stored without password to allow the script to use the key and not stopping execution by an interactive prompt for the private key password.
This puts the remote server at risk because if the originating server is compromised an attacker would easily gain access to the remote server as well. To reduce the damage of a compromised private key, one often restricts the access of the key to the minimum required to get the script's job done. This can be accomplished by using SSH-key options in the authorized_keys file.
Example:
This is quite effective, and restricts the attacker to executing the specified forced command, and only from a specified host, with no terminal or X11 access.
Other times one needs to do a sync job using rsync. Let's see how that works out with the above scheme.
Example command:
Example entry in authorized_keys:
Trying that, you'll soon noticed that all your command line arguments are ignored, and you'll get the help text from rsync as output. The forced command option does not allow arbitrary command line arguments to the command.
There is a workaround by using the
This will produce this command:
A solution to this is the wrapper script that interprets the environment variable and executes the correct command:
This adds complexity and requires a script to be installed on the remote server. It is also possible to achieve a similar solution without the wrapper script:
Notice the
There are some security concerns however. For instance this would be possible from the machine "fromserver.example.com":
That would allow an attacker to swap the file with anything, and thus the security is easily breached. To prevent that, make the file owned by root and remove write permissions on the file, or make it immutable with chattr.
Allowing the unrestricted use of the rsync program will allow an attacker to replace any files the user has write access to. Beware that there probably are other holes in this that I didn't find.
This puts the remote server at risk because if the originating server is compromised an attacker would easily gain access to the remote server as well. To reduce the damage of a compromised private key, one often restricts the access of the key to the minimum required to get the script's job done. This can be accomplished by using SSH-key options in the authorized_keys file.
Example:
from="fromserver.example.com",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="/home/user/bin/script.sh" ssh-rsa AAAAB3NzA..Dxq= user@fromserver.example.com
This is quite effective, and restricts the attacker to executing the specified forced command, and only from a specified host, with no terminal or X11 access.
Other times one needs to do a sync job using rsync. Let's see how that works out with the above scheme.
Example command:
/usr/bin/rsync /some/dir/ user@remote.example.com:/some/other/dir/
Example entry in authorized_keys:
from="fromserver.example.com",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="/usr/bin/rsync" ssh-rsa AAAAB3NzA..Dxq= user@fromserver.example.com
Trying that, you'll soon noticed that all your command line arguments are ignored, and you'll get the help text from rsync as output. The forced command option does not allow arbitrary command line arguments to the command.
There is a workaround by using the
$SSH_ORIGINAL_COMMAND
environment variable that the ssh program creates. The problem with that is that you'll need a wrapper script to deal with the arguments because it will have the executable twice in the argument list:from="fromserver.example.com",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="/usr/bin/rsync $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAB3NzA..Dxq= user@fromserver.example.com
This will produce this command:
/usr/bin/rsync /usr/bin/rsync /some/dir/ user@remote.example.com:/some/other/dir/
A solution to this is the wrapper script that interprets the environment variable and executes the correct command:
#!/bin/bash case $SSH_ORIGINAL_COMMAND in "/usr/bin/rsync "*) $SSH_ORIGINAL_COMMAND ;; *) echo "Permission denied." exit 1 ;; esac
This adds complexity and requires a script to be installed on the remote server. It is also possible to achieve a similar solution without the wrapper script:
from="fromserver.example.com",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="/usr/bin/rsync ${SSH_ORIGINAL_COMMAND#* }"
Notice the
'#* '
right after SSH_ORIGINAL_COMMAND
. The #
modifier in bash is used to remove the smallest prefix pattern, and so '#* '
will remove everything up until and including the first space.There are some security concerns however. For instance this would be possible from the machine "fromserver.example.com":
rsync authorized_keys user@server:/home/user/.ssh/authorized_keys
That would allow an attacker to swap the file with anything, and thus the security is easily breached. To prevent that, make the file owned by root and remove write permissions on the file, or make it immutable with chattr.
chown root:root /home/user/.ssh/authorized_keys
chmod a-w /home/user/.ssh/authorized_keys
chattr +i /home/user/.ssh/authorized_keys
Allowing the unrestricted use of the rsync program will allow an attacker to replace any files the user has write access to. Beware that there probably are other holes in this that I didn't find.
mandag 13. september 2010
Managing GlassFish domains with Puppet
Following James Turnbull's plugin HOWTO, I've created a new Puppet resource type for managing GlassFish domains. You can get it via the Puppet Forge.
This plugin is meant to replace the previously used (with success) exec type for managing GlassFish domains:
his new resource type allows for more functionality and expressive clarity than the exec type. For example, it allows you to easily delete the domain by using the
I plan to add more features to it, such as adding system-properties and jvm-options.
This plugin is meant to replace the previously used (with success) exec type for managing GlassFish domains:
$passfile = "/home/gfish/.aspass"
$portbase = "4900"
$asadmin = "/opt/NSBglassfish/bin/asadmin"
$domaindir = "/opt/NSBglassfish/glassfish/domains"
exec {
"create-domain-$name":
command => "$asadmin --user admin --passwordfile $passfile create-domain --profile cluster --portbase $portbase --savelogin $name",
user => "admin",
creates => "$domaindir/$name";
}
his new resource type allows for more functionality and expressive clarity than the exec type. For example, it allows you to easily delete the domain by using the
ensure => absent
property. This is how one specifies a new GlassFish domain with this:glassfish {
"mydomain":
portbase => "4800",
adminuser => "admin",
passwordfile => "/home/gfish/.aspass",
profile => "cluster",
ensure => present;
"myolddomain":
ensure => absent;
}
I plan to add more features to it, such as adding system-properties and jvm-options.
mandag 24. mai 2010
Parsing the /etc/passwd file with Ruby
I decided to write a program to parse the /etc/passwd file in my favourite scripting language. The file has seven fields: user, password, UID, GID, GECOS, home and shell.
Writing this snippet of code, I used some metaprogramming features in Ruby that I learned from Metaprogramming Ruby by Paolo Perrotta, like "OpenStruct", Dynamic Methods and method_missing(). I created a structure to hold the field information for each line in the file like this:
To show an example of useage, we can print each field, like this:
Writing this snippet of code, I used some metaprogramming features in Ruby that I learned from Metaprogramming Ruby by Paolo Perrotta, like "OpenStruct", Dynamic Methods and method_missing(). I created a structure to hold the field information for each line in the file like this:
class PasswdFile
class PasswdEntry
def initialize
@attributes = {}
end
def method_missing(name, *args)
attribute = name.to_s
if attribute =~ /=$/
@attributes[attribute.chop] = args[0]
else
@attributes[attribute]
end
end
def import(line)
field_names = [:user, :password, :uid, :gid, :gecos, :home, :shell]
fields = line.split(":")
puts "Error: Not a passwd line, not 7 fields" unless fields.length == 7
field_names.each do |field_name|
self.send("#{field_name}=", fields[field_names.index(field_name)])
end
end
end
attr_reader :filename
def initialize(filename="/etc/passwd")
@entries = []
import(filename)
end
def import(filename)
File.open(filename, "r").each do |line|
entry = PasswdEntry.new
entry.import line
@entries << entry
end
end
def each
@entries.each do |entry|
yield entry
end
end
def print
field_names = [:user, :password, :uid, :gid, :gecos, :home, :shell]
@entries.each do |entry|
puts "ENTRY:"
field_names.each do |field_name|
puts " #{field_name}: " + entry.send("#{field_name}")
end
end
end
end
To show an example of useage, we can print each field, like this:
entries = PasswdFile.new
entries.print
tirsdag 18. august 2009
Rooting the HTC Hero
On friday I got my new HTC Hero in the mail. Yesterday, I rooted it following instructions on phandroid.com. Instead of from Windows, like in the article on phandroid.com, I did it from Linux, and here is how.
1. Download android-sdk-linux_x86-1.5_r3.zip
2. Download orange-htc-hero-uk-boot.img-28-july-2009.zip
3. Download fastboot for Linux.
4. Run these commands:
6. Press and hold the back key and power on the phone.
This will get you into the fastboot USB screen (the white screen with three androids at the bottom).
7. Run this command:
8. In the phone's alerts menu, click HTC Sync.
9. Run this command:
10. From this shell, run these commands:
1. Download android-sdk-linux_x86-1.5_r3.zip
2. Download orange-htc-hero-uk-boot.img-28-july-2009.zip
3. Download fastboot for Linux.
4. Run these commands:
# unzip android-sdk-linux_x86-1.5_r3.zip5. Shutdown the phone and plug in the USB cable.
# unzip orange-htc-hero-uk-boot.img-28-july-2009.zip
# mv orange-htc-hero-uk-boot.img-28-july-2009/boot.img.insecure android-sdk-linux_x86-1.5_r3/tools
# unzip fastboot.zip
# mv fastboot android-sdk-linux_x86-1.5_r3/tools
# cd android-sdk-linux_x86-1.5_r3/tools
6. Press and hold the back key and power on the phone.
This will get you into the fastboot USB screen (the white screen with three androids at the bottom).
7. Run this command:
# sudo ./fastboot boot boot.img.insecureNow your device will start from the given image with root access.
downloading 'boot.img'... OKAY
booting... OKAY
8. In the phone's alerts menu, click HTC Sync.
9. Run this command:
sudo ./adb shellThis will give you a root shell on the device.
10. From this shell, run these commands:
# mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /systemNow your device is rooted!
# cp -a /system/bin/su /system/bin/su.backup
# cat /system/bin/sh > /system/bin/su
# chmod 4755 /system/bin/su
# reboot
tirsdag 11. august 2009
ZFS root disk mirror
So, I just installed OpenSolaris on a Sun Blade X6240 Server Module. I have two disks on this machine, and wanted to use disk mirroring. I didn't want to use the integrated LSI 1068E hardware RAID controller, I wanted to use the much cooler ZFS mirror feature.
During installation, it was not possible to set up mirroring, it had to wait until after the first boot. The installation wizard created the necessary partitions, ZFS filesystem and installed GRUB on the system, and I don't know what commands it has run to set up the disk the way it is now. So, to attach the mirror disk to the ZFS pool, I copied the partition table to the mirror:
Now that's done, and I proceeded to attach the mirror disk into the ZFS pool:
Installing GRUB and updating the master boot sector was also necessary to be able to boot off the mirror:
And that's that!
During installation, it was not possible to set up mirroring, it had to wait until after the first boot. The installation wizard created the necessary partitions, ZFS filesystem and installed GRUB on the system, and I don't know what commands it has run to set up the disk the way it is now. So, to attach the mirror disk to the ZFS pool, I copied the partition table to the mirror:
# prtvtoc /dev/rdsk/c8t0d0s2 | fmthard -s - /dev/rdsk/c8t1d0s2
Now that's done, and I proceeded to attach the mirror disk into the ZFS pool:
# zpool status rpool
pool: rpool
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
c8t0d0s0 ONLINE 0 0 0
errors: No known data errors
# zpool attach -f rpool c8t0d0s0 c8t1d0s0
Please be sure to invoke installgrub(1M) to make 'c8t1d0s0' bootable.
# zpool status rpool
pool: rpool
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scrub: resilver in progress for 0h0m, 15.41% done, 0h1m to go
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror ONLINE 0 0 0
c8t0d0s0 ONLINE 0 0 0
c8t1d0s0 ONLINE 0 0 0 1.07G resilvered
errors: No known data errors
Installing GRUB and updating the master boot sector was also necessary to be able to boot off the mirror:
# installgrub -m /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/c8t1d0s0
Updating master boot sector destroys existing boot managers (if any).
continue (y/n)?y
stage1 written to partition 0 sector 0 (abs 16065)
stage2 written to partition 0, 271 sectors starting at 50 (abs 16115)
stage1 written to master boot sector
And that's that!
tirsdag 21. juli 2009
BADSIG 40976EAF437D05B5
When running apt-get update today, I got this error message:
Strange. And it was no good retrying, the same error occurred over and over again. apt-get stopped complaining after running update with this option:
and this:
I suspect my company's Barracuda Spam & Virus Firewall is to blame, as it has been blamed for arbitrarily corrupting downloads before by my co-workers. How can I know for certain?
The following signatures were invalid: BADSIG 40976EAF437D05B5 Ubuntu Archive Automatic Signing Key
Strange. And it was no good retrying, the same error occurred over and over again. apt-get stopped complaining after running update with this option:
apt-get update -o Acquire::http::No-Cache=True
and this:
apt-get update -o Acquire::BrokenProxy=true
I suspect my company's Barracuda Spam & Virus Firewall is to blame, as it has been blamed for arbitrarily corrupting downloads before by my co-workers. How can I know for certain?
Abonner på:
Innlegg (Atom)