Thursday, August 27, 2009

[updated] GnuPG: PGP under Linux

Install the gnupg:

#---
yum - y install \
gnupg2
#---


To generate a key:

#---
gpg2 --gen-key
#---


To export the public key:

#---
gpg2 -a -o pubkey.asc --export <your email>
#---


To export your private key (for backup purposes only, NOT recommended):

#---
gpg2 -a -o privkey.asc --export-secret-keys <your email>
#---


To import a public key:

#---
gpg2 --import <pubkey file>
#---


To sign a key:

#---
gpg2 --sign-key <key email address>
#---


To encrypt a file, in ASCII mode:

#---
gpg2 -a -o <output file>.asc -r <your email> [-r <recipient's email>] -e <file to encrypt>
#---


To decrypt a file:

#---
gpg2 -o <output file> -d <input file>
#---


If you don't like command line you can try two GUIs:

#---
yum -y install \
kdeutils \
gpa
#---


NOTE: KDEUtils comes with KGpg which is the best among the two.

[update]

A reader (see his comment below) drove my attention a missing point: "how to import secret keys to GnuPG?" the answer is: use the old GnuPG for it:

#---
yum -y install \
gnupg
#---


To import secret keys:

#---
gpg --import <key file>
#---


Sorry, about the "hackerish" part, but it works.

PGP for Windows users

PGP for Windows:

1. Go to http://www.pgp.com/downloads/desktoptrial/desktoptrial2.html check the box at the bottom of the page and hit "Accept"
2. Fill up the form
3. Hit the Windows XP button and wait for the download link

NOTE: Because you will use the trial version, which will switch to the freeware featured version after 30 days, be aware that only the basic features will remain active. From the agreement form you get:

What functionality continues after 30 days?
The following limited functionality (equivalent to prior versions of PGP Freeware) will continue after the initial 30-day period:

At the end of the trial period, any local disks that have been encrypted using PGP Whole Disk Encryption will automatically decrypt.

PGP file encryption and signing, PGP Zip, “Current Window”, and “Clipboard” functionality will continue to allow encryption, and you will still be able to use the decryption capabilities for all PGP Desktop Trial product functions, thus ensuring that any encrypted data remains accessible.


Installation and configuration (requires a restart at the end of the installation process):

It is pretty straight forward, but you can follow the instructions received with the download link. I'm not going to show how, but some attention must be given to the following points:

Generate your key as the pictures show, if you are concerned with Linux GnuPG compatibility, some encryption algorithms are copyright protected and are not implemented in GnuPG.





To import keys:

1. Open the PGP Desktop: Start -> PGP -> PGP Dektop
2. On PGP Desktop: Menu File -> Import...
3. Select the key file(s)
4. When the keys are on the key list, select all of them
5. Sign them: Menu Keys -> Sign...

To put on your Master Keyring:

1. Open the PGP Desktop: Start -> PGP -> PGP Dektop
2. Select one key (you need to do it "keywise", only one at a time) and: Menu Keys -> Add to Master Keys

To export your public key:

1. Open the PGP Desktop: Start -> PGP -> PGP Dektop
2. Select your key
3. Menu File -> Export -> Key...

NOTE: Do NOT check the "Include Private Key(s)" field.

To encrypt a file:

Right mouse button at the file and: PGP Desktop -> Encrypt to Master Keys...

SSH in a more secure way

SSH is a wonderful tool, I cann't praise it enough. But as all powerful tools it requires special attention to its use. In this post I want to put good recommendations into action. The guidelines are:

1. No "root" direct access;
2. Only ONE user should have remote access to the system AND "su" rights;
3. All users with full featured shells, except for the one with "su" rights, should NOT have remote access granted (you can always become any user with the access user);
4. All other users that MUST have remote access MUST have restricted shells, like "rbash".

A. The SSH server configuration at: /etc/ssh/sshd_config

(below are the excerpt from the file whose change are recommended)

# This is the default, but it is important to keep it explicit
Port 22
# If you have several interfaces it may be good to force the access to be from a specific network interface/address or mask, this is your server IP address or IP masked range.
# using 192.168.0.0 will NOT grant access to someone addressing your server outside the 192.168.X.X range.
ListenAddress 0.0.0.0
# Enforce the use of ONLY the version 2
Protocol 2
# Turns root remote access off
PermitRootLogin no
# Will log authentication failures when half the amount is tried: it does NOT block access JUST logs failures
MaxAuthTries 4
# If your clients are not behind a proxy it is wise to restrict the amount of open sessions that a single host can make to your machine
MaxSessions 4
# This can be a security issue. Suit yourself (I need it for CruiseControl)
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
# I really like PAM
UsePAM yes
# This can be really annoying if you have several users trying to connect simultaneously, but it helps to prevent brute-force attacks to your server, keep it low.
MaxStartups 2


B. The PAM setup at: /etc/pam.d/sshd

(add the following line)

auth required pam_listfile.so item=user sense=allow file=/etc/sshd/sshd.allow onerr=fail

This line tells PAM to look for the file /etc/sshd/sshd.allow for the users that are ALLOWED to access your server through SSH. This file should contain only the users that REALLY need direct remote access.

#---
cat > /etc/ssh/sshd.allow << __END__
SU_user
rbash_user
__END__
chown root:root /etc/ssh/sshd.allow
chmod 400 /etc/ssh/sshd.allow
#---


C. The IPTABLES part at: /etc/sysconfig/iptables

(Add or modify the following line):

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

D. Restart the servers:

#---
service sshd restart
service iptables restart
#---


Have fun!!!

Reference:

http://www.cyberciti.biz/tips/linux-pam-configuration-that-allows-or-deny-login-via-the-sshd-server.html

Friday, August 14, 2009

[updated] CruiseControl: Config

Before following this post you need an SVN server (post here) and a CruiseControl server (post here and here).

1. Create a special account, on the SVN server, for getting the source code from the CC server.

The objective here is to do something similar to what is described at http://svn.collab.net/repos/svn/trunk/notes/ssh-tricks

1.1. [SVN Server] On the SVN server:

1.1.1. Add two new SVN access accounts, but without shell access:

#---
useradd svn-ro
useradd svn-rw
usermod --lock svn-ro
usermod --lock svn-rw
#---


1.1.2. Verify if the SSH daemon is setup to accept public key authentication: /etc/ssh/sshd_config

It must have a line with:

PubkeyAuthentication yes

1.2. [CC Server] On the CC server:

1.2.1. Setup the key pair for the cruise user, to be used to authenticate at the SVN server (see documentation here):

a. Enter an EMPTY passphrase for the ssh key pair:

#---
mkdir ~cruise/.ssh
ssh-keygen -q -f ~cruise/.ssh/id_rsa -t rsa
#---


b. Let the user have access to own keys, but only this user:

#---
chmod -R go-rwx ~cruise/.ssh
chown -R cruise:cruise ~cruise/.ssh
#---


1.2.3. Copy the public key to the SVN server, at the svn-ro user home dir (remember that svn-ro user has no shell access, so do NOT try to transfer the key using the svn-ro account).

#---
scp ~cruise/.ssh/id_rsa.pub <user that HAS shell access in the SVN server>@<SVN server>:
#---


1.3. [SVN Server] Back at the SVN server:

1.3.1. Add the public key to the svn access user's (svn-ro) authorized key ring:

#---
mkdir -p ~svn-ro/.ssh/
mkdir -p ~svn-rw/.ssh/
cat ~<user used to deploy the public key>/id_rsa.pub >> ~svn-ro/.ssh/authorized_keys
cat ~<user used to deploy the public key>/id_rsa.pub >> ~svn-rw/.ssh/authorized_keys
chown -R svn-ro:svn-ro ~svn-ro/.ssh/
chmod -R go-rwx ~svn-ro/.ssh/
chown -R svn-rw:svn-rw ~svn-rw/.ssh/
chmod -R go-rwx ~svn-rw/.ssh/
#---


1.3.2. Edit the authorization key ring file: ~svn-ro/.ssh/authorized_keys AND ~svn-rw/.ssh/authorized_keys

a. It looks like this:

ssh-rsa AAAA<a lot more chars>= root@<CC server name>

b. change it to this:

command="/usr/bin/svnserve -t",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAA<a lot more chars>= root@<CC server name>

1.4. [CC Server] Back to the CC server:

1.4.1. Create the necessary directories for the CC:

#---
mkdir -p /var/spool/cruisecontrol/{projects,logs,artifacts}
chown -R cruise:cruise /var/spool/cruisecontrol/
#---

1.4.1. Try to access the SVN server:

#---
su - cruise
svn list svn+ssh://svn-ro@<SVN server>/var/svn/
logout
#---


2. Configuring a project to be managed under the CC policy:

a. Local working copy (for the CruiseControl): /var/spool/cruisecontrol/projects
b. Special SVN repository for the CruiseControl configuration and building ANT scripts: /var/svn/cruisecontrol
c. A special SVN Project (under the /var/svn/trunk) to hold the main build and JUnit ANT scripts, that is called Master here

2.1. [SVN Server] Create the new CC root at the SVN

#---
svn mkdir -m "Initial setup: CruiseControl development tree" file:///var/svn/cruisecontrol
#---


2.4. [Dev Workstation] Create a project, named Main, and commit/import it to svn+ssh://<SVN server>/var/svn/cruisecontrol

Note.: This project must contain at least one file called build-cc.xml.

2.5. [SVN Server] To keep it simple:

#---
su - <A regular dev user>
mkdir Main
cd Main
cat > build-cc.xml << __END__
<project basedir="." default="main" name="Main">
<target name="main">
<echo message="Working"/>
</target>
</project>
__END__
svn import -m "Initial CruiseControl build file" file:///var/svn/cruisecontrol/Main
#---


2.6. [CC Server] Checkout the CC root from the SVN at the local working dir: /var/spool/cruisecontrol/projects

#---
su - cruise
svn checkout svn+ssh://svn-ro@<SVN Server>/var/svn/cruisecontrol/Main projects/Main
logout
#---


2.3. [CC Server] Create a new config.xml

[UPDATE: NOT WORKING PROPERLY] (Thanks to Leif, see comments below).

#---
cat > /etc/cruisecontrol/config.xml << __END__
<cruisecontrol>
<property name="cruise.working.dir" value="/var/spool/cruisecontrol" />
<property name="cruise.log.dir" value="\${cruise.working.dir}/logs" />
<property name="cruise.projects.dir" value="\${cruise.working.dir}/projects" />
<property name="svn.sandbox.username" value="svn-ro" />
<plugin name="basicproject" classname="net.sourceforge.cruisecontrol.ProjectConfig">
<labelincrementer defaultLabel="\${project.name}-1"
separator="-" />
<listeners>
<currentbuildstatuslistener
file="\${cruise.log.dir}/\${project.name}/status.txt" />
</listeners>
<modificationset quietperiod="30">
<svn LocalWorkingCopy="\${cruise.projects.dir}/\${project.name}" />
</modificationset>
<log>
<merge
dir="\${cruise.working.dir}/projects/\${project.name}/target/test-results" />
</log>
<publishers>
<artifactspublisher
file="\${cruise.working.dir}/projects/\${project.name}/target/\${project.name}.jar"
dest="\${cruise.working.dir}/artifacts/\${project.name}" />
</publishers>
</plugin>
<!-- here you can change the project name, if you decided from something else -->
<project name="Main" buildafterfailed="yes"
forceBuildNewProject="yes">
<bootstrappers>
<svnbootstrapper localWorkingCopy="\${cruise.projects.dir}/\${project.name}"
userName="\${svn.sandbox.username}" />
</bootstrappers>
<schedule interval="10">
<ant antWorkingDir="\${cruise.projects.dir}/\${project.name}"
buildfile="build-cc.xml" />
</schedule>
</project>
</cruisecontrol>
__END__
#---


[UPDATE]

2.4. [CC Server] Restart the server and check if it worked by accessing: http://localhost:8080/dashboard/

3. Have fun, configuring the build-cc.xml and organising your repository and code :-)


Related posts:
Subversion and Apache with PAM
CruiseControl on Fedora: Setup
CruiseControl on CentOS: Setup

CruiseControl on CentOS: Setup

In this post I want to present a simple way to install and configure CruiseControl (hereafter just CC) to run on CentOS. For the configuration part, please refer to the Fedora procedure, since it is the same. The only difference is in how to install the CC to be similar to the RPM instalation.

1. Since I could not find any RPM specific for CentOS I have taken the binaries available at CC home-page: http://cruisecontrol.sourceforge.net/download.html

You will also need the following packages:

#---
yum -y install \
ant
#---


And Sun's Java JDK: http://java.sun.com/javase/downloads

2. Decompress the binary package from CC into /opt dir:

#---
unzip cruisecontrol-bin-<VERSION>.zip -d /opt/
ln -s /opt/cruisecontrol-bin-<VERSION> /opt/cruisecontrol
#---


3. Edit the starting script at: /opt/cruisecontrol/cruisecontrol.sh

3.1. Add the following lines, right after the commented CC_OPTS variable:

JAVA_HOME="/usr/java/default/jre"
PATH=${JAVA_HOME}/bin:${PATH}


3.2. Check if the default port is free:

#---
nc -z localhost 8080 || echo "Port is free" # default cruise control port AND tomcat's default port, watch this out
#---


OBS.: It MUST yeld NOTHING. If it returns a "succeeded" it means that the port is occupied and you need to change it to another one.

3.3. Change the final calling statements for:

#---
cat >> /opt/cruisecontrol/cruisecontrol.sh << __END__
# PAY ATTENTION: you ABSOLUTELY need to change the argument in the \"-webport\" if the port 8080 is already occupied
CMD="JAVA_HOME=\${JAVA_HOME:-/usr} \\
PATH=\${JAVA_HOME:-/usr}/bin:\$PATH \\
CC_OPTS=\"\${CRUISE_OPTS:-}\" \\
\$JAVA_HOME/bin/java \\
-Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder \\
\"-Dcc.library.dir=\$LIBDIR\" \\
\"-Djetty.logs=$JETTY_LOGS\" \\
-jar \"\$LAUNCHER\" \$@ \\
-configfile /etc/cruisecontrol/config.xml \\
-jmxport \${CRUISE_JMX_PORT:-8000} \\
-rmiport \${CRUISE_RMI_PORT:-1099} \\
-webport \${CRUISE_WEB_PORT:-8080} \\
&"

echo \$CMD
# necessary to make the "out-of-box" version work regardless of the calling point
cd /var/spool/cruisecontrol/
eval \${CMD}
echo \$! > /var/spool/cruisecontrol/cc.pid
__END__
mv /opt/cruisecontrol/cruisecontrol.sh /opt/cruisecontrol/cruisecontrol2.sh
cat > /opt/cruisecontrol/cruisecontrol.sh << __END__
#!/bin/sh
su - cruise -c /opt/cruisecontrol/cruisecontrol2.sh
__END__
chmod 755 /opt/cruisecontrol/cruisecontrol.sh
#---


4. Add the cruise user:

#---
groupadd cruise
useradd \
--comment "CruiseControl User" \
--home-dir "/var/spool/cruisecontrol" \
--gid cruise \
--shell /bin/bash \
cruise
#---


5. Verify if CC is running:

#---
/opt/cruisecontrol/cruisecontrol.sh
#---


5.1. Check if it is up and running by accessing: http://localhost:8080/dashboard (remember that if you changed the default port the value 8080 must be changed as well).

5.2. If it is up and running you may want to make it starts when the server starts:

#---
cat >> /etc/rc.local << __END__

# starts the CruiseControl
/opt/cruisecontrol/cruisecontrol.sh
__END__
#---


Related post: CruiseControl on Fedora: Setup

CruiseControl on Fedora: Setup

In this post I want to present a simple way to install and configure CruiseControl (hereafter just CC) to run on Fedora. It is NOT my objective to teach you how to each and every option of the configuration file works. For that you have plenty of other sources, such as the official documentation (here) and a pretty good step-by-step install, configure, and use documentation at JavaRanch (here). My objective is to give you an example of how to install and configure a CC server. (I'm one of those guys that learn better with an example.) Feel free to adapt it to your necessities.

http://cruisecontrol.sourceforge.net/main/configxml.html
http://www.javaranch.com/journal/200409/DrivingOnCruiseControl_Part1.html

1. Since I could not find any RPM specific for Fedora I have taken the RPM for OpenSUSE from RPMpbone.net (package list here and here):

You will also need the following packages:
#---
yum -y install \
ant
#---


And Sun's Java JDK: http://java.sun.com/javase/downloads

2. Setup the CC service.

Set it to use the Sun Java (it has serious problem with openJDK) by editing the file: /etc/default/cruisecontrol and including the following lines, before the final line

JAVA_HOME="/usr/java/default/jre"
PATH=${JAVA_HOME}/bin:${PATH}


2.1. Check if the default port is free:

#---
nc -z localhost 8080 # default cruise control port AND tomcat's default port, watch this out
#---


OBS.: It MUST yeld NOTHING. If it returns a "succeeded" it means that the port is occupied and you need to change it to another one. You can change it by given another port number for the variable CRUISE_WEB_PORT in the file: /etc/default/cruisecontrol

2.2. Start the CC daemon:

#---
service cruisecontrol start
#---


2.3. Check if it is up and running by accessing: http://localhost:8080/dashboard (remember that if you changed the default port the value 8080 must be changed as well).

2.4. If it is up and running you may want to make it starts when the server starts:

#---
chkconfig --level 345 cruisecontrol
#---


Related post: CruiseControl on CentOS: Setup

Tuesday, August 04, 2009

Sending emails from server without a local smtp server

First of all, I do not like to have unnecessary daemons running on a server that are not related to the server's function and the excuse that it is easier that way does not convince me. So here is a cookbook recipe to send emails from a server without using the local smtp server (very useful for CRON scripts and other maintenance scripts).

1. You need to install mailx:

#---
yum -y install \
mailx
#---


NOTE.: For CentOS you will need nail instead of mailx (they crippled mailx in CentOS):

1.1. Install the repository from http://centos.karan.org/:

#---
wget http://centos.karan.org/kbsingh-CentOS-Extras.repo -O /etc/yum.repos.d/kbsingh-CentOS-Extras.repo
#---


1.2. Install nail:

#---
yum --enablerepo=kbs-CentOS-Testing -y install \
nail
#---


2. You need a copy of your SSL root certificates in the server.

2.1. On your client box, transfer your SSL certificates to the server:

#---
scp $HOME/.mozilla/firefox/<something>.default/cert<a number>.db <server ssh user>@<your server>:/path/you/can/write
#---


2.2. Go to the server and put the certificate db at some path your script has access to

3. Create a GMail account, that will be the sender in your scripts (the password will be stored on the script, so do NOT use one of your accounts)

4. On your script put the following a line like the following:

#---
mail \
-S smtp-use-starttls \
-S smtp=smtp://smtp.gmail.com:587 \
-S smtp-auth=login \
-S smtp-auth-user=<username gmail>@gmail.com \
-S smtp-auth-password=<the account password> \
-S from="<username gmail>@gmail.com" \
-S nss-config-dir=<where you stored the certificates DB file> \
-S ssl-verify=ignore \
-s "<email subject>" <to whom the email must be sent>
#---


4.1. If you are in a CentOS box, change the command mail for nail in the above command line and all will work perfectly.