[xwiki-users] totally groovy! (using groovy SSH script to securely launch unix processes out of Xwiki)

2009-08-11 Thread Niels Mayer
This might be useful for those wanting to do server administration functions
(start/stop tomcat, reboot, stats, etc) out of an Xwiki doc (make sure your
doc is password protected or more, if it allows people to reboot your
server!; Anything needing root or tomcat user would use /etc/sudoers to
grant specfic permissions to specific programs needed by user
tomcat-ssh-slave):

Input:

  Use Groovy Script run server processes and display result 


 See [[SshHelperClass?viewer=code]], [[
 http://blog.asyd.net/2008/12/xwiki-cest-decidemment-magique/]]


  Call parseGroovyFromPage(Groovy.SshHelperClass) 

{{velocity}}

#set( $sshHelper = $xwiki.parseGroovyFromPage(Groovy.SshHelperClass) )

$sshHelper.openSession(127.0.0.1, 22, tomcat-ssh-slave,
 /usr/share/tomcat6/.ssh/id_dsa, )

{{/velocity}}


  Output from 'uname -a'

##{{velocity}}$sshHelper.runCommand(uname -a){{/velocity}}##


  Output from 'free' 

##{{velocity}}$sshHelper.runCommand(free){{/velocity}}##


  Output from 'ps -l U tomcat-ssh-slave U tomcat U apache' 

##{{velocity}}$sshHelper.runCommand(ps -l h U tomcat-ssh-slave U tomcat U
 apache){{/velocity}}##


  Output from 'df -H' 

##{{velocity}}$sshHelper.runCommand(df -H){{/velocity}}##


  Output from 'top -b -n 1' 

##{{velocity}}$sshHelper.runCommand(top -b -n 1){{/velocity}}##


  Close the connection and exit tomcat-ssh-slave shell 

warning: if something breaks above, hopefully this will get called otherwise
 we

get a left-over sub-process tomcat-ssh-slave

##{{velocity}}$sshHelper.close(){{/velocity}}##


Output:

 Use Groovy Script run server processes and display result

 See SshHelperClass ,
 http://blog.asyd.net/2008/12/xwiki-cest-decidemment-magique/

 *Call parseGroovyFromPage(Groovy.SshHelperClass)*

 *Output from 'uname -a'*

 Linux ce 2.6.27.29-170.2.78.fc10.x86_64 #1 SMP Fri Jul 31 04:16:20 EDT
 2009 x86_64 x86_64 x86_64 GNU/Linux

 *Output from 'free'*

 total used free shared buffers cached

 Mem: 1928992 1778932 150060 0 47272 532128

 -/+ buffers/cache: 1199532 729460

 Swap: 3866616 78776 3787840

 *Output from 'ps -l U tomcat-ssh-slave U tomcat U apache'*

 5 S 92 18792 18788 0 80 0 - 22060 select ? 0:00 sshd:
 tomcat-ssh-sl...@notty

 0 R 92 18879 18792 1 80 0 - 22453 - ? 0:00 ps -l h U tomcatssh-slave U
 tomcat U apache

 0 S 91 31695 1 0 80 0 - 463955 futex_ ? 7:47 /usr/java/default/bin/java
 -server -Xms160m -Xmx1024m -XX:PermSize=160m -XX:MaxPermSize=320m ...

 *Output from 'df -H'*

 Filesystem Size Used Avail Use% Mounted on

 /dev/mapper/VolGroup00-LogVol00 242G 26G 204G 12% /

 /dev/sda1 200M 15M 175M 8% /boot

 tmpfs 988M 353k 988M 1% /dev/shm

 *Output from 'top -b -n 1'*

 top - 11:17:20 up 2 days, 16:21, 3 users, load average: 0.78, 0.68, 0.56

 Tasks: 150 total, 2 running, 148 sleeping, 0 stopped, 0 zombie

 Cpu(s): 7.7%us, 1.7%sy, 0.0%ni, 90.2%id, 0.3%wa, 0.1%hi, 0.1%si, 0.0%st

 Mem: 1928992k total, 1794420k used, 134572k free, 47304k buffers

 Swap: 3866616k total, 78776k used, 3787840k free, 532356k cached

  ...


Special Installation Instructions

To make this run (Fedora Linux):
1. sudo yum install trilead-ssh2 trilead-ssh2-javadoc
2. sudo ln -s /usr/share/java/trilead-ssh2-213.jar
/usr/share/java/tomcat6/trilead-ssh2.jar
3. Make sure tomcat user exists in /etc/passwd, and create an additional
uid=92 gid=92 account tomcat-ssh-slave:
• tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/bin/sh
° tomcat user created as disabled by installing tomcat6-6.0.18-6.2.fc10
• tomcat-ssh-slave:x:92:92:User for SSH Subprocesses From
Tomcat:/home/tomcat-ssh-slave:/bin/bash
° create this using fedora admin utility 'system-config-users' or by
hand-editing /etc/passwd...
4. sudo passwd -u tomcat
• unlock tomcat account temporarily
5. sudo passwd tomcat
• set password for tomcat account
6. Login to tomcat account using SSH from current account terminal.
7. ssh-keygen -t dsa
• Leave empty for no passphrase for decrypting the DSA-key produced by
ssh-keygen, although it can be specified as last parameter for
sshHelper.openSession(localhost, 22, tomcat-ssh-slave,
/usr/share/tomcat6/.ssh/id_dsa, ).
8. From the tomcat account, run ssh tomcat-ssh-sl...@127.0.0.1
• answer Yes: Are you sure you want to continue connecting (yes/no)? yes
• enter password for tomcat-ssh-slave set above via system-config-users.
• exit the connection.
• The purpose of this step is to test the account, and init
/usr/share/tomcat6/.ssh/known_hosts
9. sudo cp /usr/share/tomcat6/.ssh/id_dsa.pub
tomcat-ssh-slave/.ssh/authorized_keys
10. From the tomcat account, do ssh tomcat-ssh-sl...@127.0.0.1 again
• verify that login happens w/o password prompt, which is what happens when
authorized_keys is set to the
public key of the account accessing SSH.
• exit from tomcat-ssh-slave account. It's now ready to run out of tomcat.
11. passwd -l tomcat
• lock the tomcat account from further logins, now that it's been setup and
the dsa public/private keys have 

Re: [xwiki-users] totally groovy! (using groovy SSH script to securely launch unix processes out of Xwiki)

2009-08-11 Thread Niels Mayer
I forgot to include the Groovy script itself that does all the heavy-lifting
in my previous mail - see Groovy.SshHelperClass below. Also, there's a much
better way of calling this groovy sshHelper class out of a single groovy
invocation in a 2.0 document. Groovy directly outputs wikitext, the renderer
takes care of the rest.

 Use Groovy Script run server processes and display result 

See [[SshHelperClass?viewer=code]], [[
http://blog.asyd.net/2008/12/xwiki-cest-decidemment-magique/]]

{{groovy}}
println  Call parseGroovyFromPage('Groovy.SshHelperClass') 
  def sshHelper = xwiki.parseGroovyFromPage(Groovy.SshHelperClass)
  sshHelper.openSession(127.0.0.1, 22, tomcat-ssh-slave,
/usr/share/tomcat6/.ssh/id_dsa, )
println  Output from 'uname -a' 
println ## + sshHelper.runCommand(uname -a) + ##
println  Output from 'free' 
println ## + sshHelper.runCommand(free) + ##
println  Output from 'ps -l U tomcat-ssh-slave U tomcat U apache' 
println ## + sshHelper.runCommand(ps -l h U tomcat-ssh-slave U tomcat U
apache) + ##
println  Output from 'df -H' 
println ## + sshHelper.runCommand(df -H) + ##
println  Output from 'top -b -n 1' 
println ## + sshHelper.runCommand(top -b -n 1) + ##
println  Close the connection and exit tomcat-ssh-slave shell 
  sshHelper.close()
{{/groovy}}

However, the Groovy.SshHelperClass script must be saved as a 1.0 document in
order to call it at the top level via:
xwiki.parseGroovyFromPage(Groovy.SshHelperClass). Is there a 2.0 syntax
that works with parseGroovyFromPage()?

Groovy.SshHelperClass in xwiki/1.0 format  (with special comment hacks per
http://platform.xwiki.org/xwiki/bin/view/DevGuide/GroovyClassHelloWorldTutorial):
...
/* Groovy Class for [SshHelperTest], orig [
http://blog.asyd.net/wp-content/uploads/2008/12/sshhelper.groovy] #* */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.Session;
import com.trilead.ssh2.StreamGobbler;

/**
 *
 * @author asyd, modified by NielsMayer
 */
class SshHelper {
def connection
def session

void openSession(hostname, port, username, identityfile, password) {
def identityIOFile = new File(identityfile)
this.connection = new Connection(hostname, Integer.parseInt(port))
this.connection.connect()
if (!connection.authenticateWithPublicKey(username, identityIOFile,
password)) {
println Authentication failed!
}
}

String runCommand(command) {
this.session = connection.openSession()
this.session.execCommand(command)
def stdoutStream = new StreamGobbler(this.session.getStdout())
def stdoutReader = new BufferedReader(new
InputStreamReader(stdoutStream))
def lineout = 
def stdoutOutput = 
while ((lineout = stdoutReader.readLine()) != null) {
stdoutOutput += (lineout + \n)
}
this.session.close()
this.session = null
return stdoutOutput
}

void close() {
if (this.session != null) {
this.session.close()
}
this.connection.close()
}
/* *# */
...

-- Niels
http://nielsmayer.com
___
users mailing list
users@xwiki.org
http://lists.xwiki.org/mailman/listinfo/users


Re: [xwiki-users] totally groovy! (using groovy SSH script to securely launch unix processes out of Xwiki)

2009-08-11 Thread Niels Mayer
Of course, one can forgo the 1.0 document and calling parseGroovyFromPage(),
and just put the class directly inside one's 2.0 groovy script and call new
SshHelper(). Of course, this still doesn't solve the problem of wanting to
reuse groovy classes across multiple documents, while wanting to use Xwiki
documents for the groovy code for easier development. Thus I still seek a
2.0-compatible version of parseGroovyFromPage('Groovy.SshHelperClass')...
Here's the all-in-one version of the previous
SSH/groovy/run-a-unix-process-out-of-a-webpage example


 Standalone version of SshHelperTest 

See also [[HowtoSetupUserTomcatSshSlave]] [[SshHelperTest]] [[
http://blog.asyd.net/2008/12/xwiki-cest-decidemment-magique/]]

{{groovy}}
/* orig [http://blog.asyd.net/wp-content/uploads/2008/12/sshhelper.groovy]
#* */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.trilead.ssh2.Connection;
import com.trilead.ssh2.Session;
import com.trilead.ssh2.StreamGobbler;

/**
 *
 * @author asyd, modified by NielsMayer
 */
class SshHelper {
def connection
def session

void openSession(hostname, port, username, identityfile, password) {
def identityIOFile = new File(identityfile)
this.connection = new Connection(hostname, Integer.parseInt(port))
this.connection.connect()
if (!connection.authenticateWithPublicKey(username, identityIOFile,
password)) {
println Authentication failed!
}
}

String runCommand(command) {
this.session = connection.openSession()
this.session.execCommand(command)
def stdoutStream = new StreamGobbler(this.session.getStdout())
def stdoutReader = new BufferedReader(new
InputStreamReader(stdoutStream))
def lineout = 
def stdoutOutput = 
while ((lineout = stdoutReader.readLine()) != null) {
stdoutOutput += (lineout + \n)
}
this.session.close()
this.session = null
return stdoutOutput
}

void close() {
if (this.session != null) {
this.session.close()
}
this.connection.close()
}
}

/*
 * Using class above, open an SSH connection to tomcat-ssh-slave
 * using user tomcat6's private key created via 'ssh-keygen -t dsa'
 * while logged in as ~tomcat6
 */
def sshHelper = new SshHelper();
sshHelper.openSession(127.0.0.1, 22, tomcat-ssh-slave,
  /usr/share/tomcat6/.ssh/id_dsa, )

println  Output from 'uname -a' 
println ## + sshHelper.runCommand(uname -a) + ##
println  Output from 'free' 
println ## + sshHelper.runCommand(free) + ##
println  Output from 'ps -l U tomcat-ssh-slave U tomcat U apache' 
println ## + sshHelper.runCommand(ps -l h U tomcat-ssh-slave U tomcat U
apache) + ##
println  Output from 'df -H' 
println ## + sshHelper.runCommand(df -H) + ##
println  Output from 'top -b -n 1' 
println ## + sshHelper.runCommand(top -b -n 1) + ##
println  Close the connection and exit tomcat-ssh-slave shell 

sshHelper.close()
/* *# */
{{/groovy}}

-- Niels
http://nielsmayer.com
___
users mailing list
users@xwiki.org
http://lists.xwiki.org/mailman/listinfo/users