Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a server written in Perl that clients connect to in order to perform some management tasks. Without going into details I would like to achieve two things:

  1. encrypt connection channel between server and client - it can be done with IO::Socket::SSL.
  2. authenticate client with SSH keys - I do not know how to do that, yet.

The best solution would be to merge these two requirements into one and have a mechanism that works exactly like SSH connection/authentication. Is that possible?

Thanks.

share|improve this question
1  
I would consider this a programming question and therefore vote to migrate to StackOverflow. –  SvW Feb 27 '12 at 12:11

4 Answers 4

You want to use a SSH tunnel. This will encrypt your communication and authenticates with SSH keys.

If you want the client to be written in perl, then use something like the Net::SSH::Perl module: http://search.cpan.org/~turnstep/Net-SSH-Perl-1.34/lib/Net/SSH/Perl.pm

Without knowing more about your setup, I really can't help you fully implement the SSH tunnel.

share|improve this answer

SSH uses keys whereas SSL tends to use X.509 certificates (and SSH is not based on SSL, by the way).

A (public key) certificate is more than just a public key: it's the association between a public key, an identifier (e.g. Subject DN) and other attributes, the whole being signed (by the issuer for X.509 certificates).

When using RSA for example, it's possible to extract the public key material (modulus and public exponent) and turn it into a certificate. What's missing from this model is that SSH keys are just that, they're not "signed" or "issued" like X.509 certificates are. You'll be missing the PKI aspect often used in SSL in your model. An easy way to go around this would be to make a self-signed certificate out of it. You would then have to import it explicitly in your client to make it trusted, or import it the first time you connect to it (which is after all very similar to what happens the first time you connect to an SSH server).

The formats of RSA keys for SSH and X.509 are different, so you will need to write some code to read the modulus and exponents from the SSH keys and produce the X.509 cert and private key in a format usable by SSL stacks.

This question on StackOverflow should be of interest (although it's done the other way around).

share|improve this answer

In addition to simply tunneling the connection over SSH, as Chris Ting points out:

You could implement a SSH subsystem, which would allow your program to seamlessly integrate with SSH. To the user it would look like your program simply uses SSH keys and encryption (which it actually is on account of actually using SSH). The process is not all that well documented, though OpenSSH SFTP client and server are somewhat self-documenting.

It would require a fair amount of rewrite, depending on how clients connect and the syntax of the protocol. The obvious benefit is that it then would slip seamlessly into the user's SSH configuration.

share|improve this answer

I wrote similar server/client app a while ago. Basic design:

  • server don't do networking, it's simple script that communicates by stdin/stdout streams (like daemons executed by inetd);
  • all network and auth stuff is done by ssh/sshd, client uses ssh with key based authorization, server has an authorized_keys file with command="" option - that key always execute my server and cannot be used to access shell or other programs;

Sample .ssh/authorized_keys file:

no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding,from="10.0.0.1",command="/usr/local/bin/fsdumps-receiver" ssh-rsa AAAA.... key_comment

Mind the from="<ip>" option - access in this example is limited to one IP only.

Server code has access to some useful environment variables. Such as:

  • $ENV{'SSH_ORIGINAL_COMMAND'} - "command" (not really) passed as ssh server_ip that_command
  • $ENV{'SSH_CLIENT'} - client IP

You can use SSH_ORIGINAL_COMMAND to choose management task in your server. Client code could spawn ssh (or use Net::SSH::Perl) with this task name as argument and later send/receive data to/from server.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.