AdSense Mobile Ad

Showing posts with label ssh. Show all posts
Showing posts with label ssh. Show all posts

Sunday, February 5, 2012

Fixing Mac OS X Lion's SSH UTF-8 Issues

After switching from Mac OS X v. 10.6 (Snow Leopard) to OS X v. 10.7 (Lion), I began experiencing some weird locale-related problems when using OS X as an SSH client. The issues I experienced include, amongst others:
  • Having the terminal complain about invalid locale settings:

$ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory 
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE=UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8" 
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8" 
LC_TELEPHONE="en_US.UTF-8" 
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

  • Being unable to correctly type some characters (such as accented characters).
  • Having programs that tunnel their traffic over SSH, such as Subversion, complain about invalid locale settings during their operations:

$ svn co svn+ssh://user@repository/path
svnserve: warning: cannot set LC_CTYPE locale
svnserve: warning: environment variable LC_CTYPE is UTF-8
svnserve: warning: please check that your locale name is correct
svnserve: warning: cannot set LC_CTYPE locale
svnserve: warning: environment variable LC_CTYPE is UTF-8
svnserve: warning: please check that your locale name is correct


In fact, if you look for example at the output of the locale command seen previously, you can see how the LC_CTYPE variable is set UTF-8 while all other LC_* variables (excluding the empty LC_ALL), are set to en_US.UTF-8 (which are correct according to that server settings).

What is the SSH client shipped with Lion doing? Apparently sending incorrect values to the server. It's not just a nuisance having to fix them after logging in, provided you're able to do so: this behaviour is breaking other programs tunnelling their traffic over SSH, such as Subversion, that aren't establishing an interactive SSH tunnel for the user.

Fortunately, the fix is quick: just tell the SSH client not to send any LC_* variable:
  • Open the SSH client configuration file (/etc/ssh_config).
  • Comment out the line that instructs the SSH client to send those variables (SendEnv LANG LC_*) from the general host configuration section (Host *). You should end up with the following fragment:

Host *
# SendEnv LANG LC_*

The configuration change will be immediately applied to any SSH session opened from now on.

Hope this helps.

Friday, June 11, 2010

SSH Hangs On Exit When Using nohup

I recently discovered how ssh sometimes hangs on exit when I've launched some process with nohup. The first suspect was standard output and it costed me some time to realize that the problem was related to the input stream of the process that I had launched with nohup.

Indeed, I solved the problem (for scripts) by launching commands this way:

$ nohup my-command </dev/null &

After finding a workaround I indeed found that this is a well known "problem" but it's not a bug, insted. As far as I could check, ssh is respecting the POSIX standard when not closing the session if a process is still attached to the tty. Other programs which did not show this behavior, such as some telnet, are behaving in a non-compliant way.

Anyway, the previous workaround is fine for me.

A small tip: Should your (Open)SSH session "hang" in such a situation, you can just use the ~. sequence to disconnect it. Don't worry, your nohup-ed process will keep running anyway.

Monday, August 31, 2009

Setting up Subversion Client Access Via SSH Using TortoiseSVN

If you read so far, you're probably running your own Subversion repositories on your Solaris box. Fine! Now, let's face the next problem: some of your users needs access from a Windows client. They installed their favorite Subversion client, TortoiseSVN, and tried to checkout your repositories. But no, it does not work.

Setting up users

The first thing to do is setting up properly a bunch of user accounts for your client. If you haven't done yet, it's time to do it, now. Read here.

Preparing some keys for your users

As I told you in my previous post, the best option you have is setting up some public key for your users: configuration on the server side will be easier and your users won't need to enter a password every time they connect to your repositories. If you don't know how to do it, read this other post.

Configure TortoiseSVN

Many people get stuck here. Windows lacks the basic set of commands you need to interact with your remote system over an encrypted connection using the SSH protocol. It may sound strange to you faithful UNIX user but unfortunately that's the truth. Programs such as TortoiseSVN bring their own implementation of the SSH client, although specifically, TortoiseSVN lets you choose an alternate external client. The problem because of which people get stuck is that TortoiseSVN configuration GUI does no mention what-so-ever of SSH authentication. Nothing. That's why, once more, you should rely to The Manual just to discover that TortoiseSVN brings with it a PuTTY client, Plink, which is the command line interface to PuTTY backends.

The problem now reduces to configuring PuTTY to use a public key to authenticate you, save the session configuration and... remember its name! As Plink will use the same configuration registry as your standalone PuTTY, you'll be done.

Checkout your repository

Now that PuTTY is configured, you can check out your first repository over an SSH connection. Just remember not to use the server's URL and use PuTTY session name instead.


Now you should be able to:
  • interact with your Solaris-hosted repositories from your Windows clients...
  • ... with TortoiseSVN...
  • ... and without typing any password.

Moreover, if you set up your Solaris user accounts as I explained you in another post, the key you distributed to your user won't let them even login into your system. You and you're sysadmin will be happy!

Configuring SSH key authentication with PuTTY

If you're a UNIX user, you're probably already using SSH public key authentication. Personally, I use it to avoid typing so many passwords every time I connect to a remote machine. If you're running a Windows client you installed an SSH client to connect to your remote machines. I usually use Cygwin, which gives me an environment very simiilar to what I'm used to. If you didn't feel like installing Cygwin just to establish a SSH connection, you probably chose PuTTY.

PuTTY is a bit different: it's got no .ssh directory to read from, it brings its SSH client implementation with it. If you want to configure PuTTY to use SSH key authentication, you can just follow these steps.

Setting up your keys for PuTTY

Both if you own or not your own keys, you need another program to produce a file for PuTTY to read: PuTTYgen. When you run it, puttygen will let you import your private key and save it in a PuTTY-friendly format or, if you haven't got one, to generate your brand new key. If you prefer not being asked a password by TortoiseSVN again and again, you can just avoid protecting the key with a passphrase and store the key in a safe place. I'll repeat it: store the key in a safe place.


Once you've done with the process, you will have a ppk file you should better store in a safe place! 

Configuring PuTTY

To tell PuTTY to use your key, just open it, go to Connection/SSH/Auth and browse for your key file in the Private key file for authentication... field. Now you can save your session and you're done.


Have fun!

Monday, August 24, 2009

Setting up SSH access to Subversion repositories on Solaris 10 (with zones)

If you followed my previous installments, you're probably running some Subversion repositories in your Solaris box. Chances are you're running the Subversion daemon, svnserve, and using the svn protocol to access the repositories: in a previous post I explained how you can set it up as an inetd service and in another post I gave you a pointer to an SMF manifests' repository where you can find a manifest to configure your Subversion daemon with the Solaris SMF framework.

There's another interesting way to access your Subversion repositories: tunneling the communication with svnserve over an encrypted SSH connection.


Why SSH?

There are many reasons that may lead you to such a choice and the most important might be:

  • You're accessing your repositories from outside your network and want to use an encrypted connection.
  • You don't want to maintain (yet another) user registry into the repository configuration files and you'd rather leverage your existing authentication strategy.

With SSH you can have existing users authenticate into your Solaris instances without additional effort. If you're already using some directory service, such as Sun Java System Directory Server, you already know the benefits of centralizing your user registry. If you're not, you should consider using a directory service before starting to duplicate sensible information such as user accounts, groups and privileges. If you're planning to give access to your repositories to users outside your organization, you could think a directory is not a good choice. Well, in this post I'll show you a possible workaround.

Tasks


To configure such a solution, you have to take into account the characteristics and the consequences of using SSH to authenticate your users into the Solaris Operating System. Whether you're using a directory service or local files (passwd, group, etc.), users who are going to connect must be managed at operating system level. You'll be able to give users access to your repositories without actually allowing them to perform any other operation on your system. Paranoid administrators shouldn't worry about users logging in into their machines, if they don't want to.

Subversion client configuration also allows you to fine tune the tunnel settings: you can change the binding port or the entire command itself, if you wish to.

You will also pay attention to the repositories' permissions: connecting via SSH, under some aspects, is just like using the local file protocol. Users connecting to your repositories, then, should have appropriate permissions on the repositories' directories.

You will also be able to leverage the Solaris Zones technology to isolate your Subversion repositories and users into a non global zone.

Configuring Subversion


This is pretty easy: if you're not fine tuning the tunnel definition, there's really nothing to configure. Just invoke the Subversion client using the svn+ssh schema and the job is done.

If you wished to fine tune your tunnel settings, you can edit the Subversion client config file. This file contains a section named [tunnels]. The config file is located in the .subversion subdirectory into your $HOME. If you want to change the default behavior associated to the svn+ssh schema, just edit (or create if it's missing) a line such as:

ssh = command

To change the default port, you could use:

ssh = ssh -p portnumber

If you wanted, you could also define your own schemas:

yourschema = yourcommand

would be used when accessing the repository with the svn+yourschema schema.

Another nice feauture of the configuration file is the possibility to override the tunnel definition with an environment variable. Defining a schema with the following syntax

yourschema = $YOURVAR yourcommand

has the following effect:

  • If the variable $YOURVAR exists, it's used as the tunnel definition.
  • If the variable doesn't exist, the tunnel definition provided in the configuration file is used instead.

The default value for the SSH tunnel definition is indeed the following:

ssh = $SVN_SSH ssh

When overriding the SSH tunnel definition you may choose to setup the $SVN_SSH variable for your users instead of modyfing the Subversion configuration file. We'll use this technique later.

Setting up the repository


One thing to take into account when using the SSH tunnel is that the svnserve command will be run with your user identity. This means that the user you're logging with must have proper permissions to access the repository files. The easiest way to go is probably creating a group for your users, let's say svn-group, and gave them write access to the repository directory, repository-dir:

$ chgrp -R svn-group repository-dir

$ chmod -R g+w repository-dir

If you're setting up multiple repositories you can create a group for each one of them. Please take into account that the Solaris operating systems allows an user to belong to a maximum of NGROUPS_MAX groups. If you also need to change the current group membership of an user because the required group is a Solaris secondary group, you can wrap the svnserve command into a script which changes the current user's group with the newgrp command.

Another good practice is setting a sane umask before accessing the repository files. You could wrap the svnserve command, or even the svn command if you're using the file schema too, into a shell script which sets the umask for the user:

#!/bin/sh
umask 002
# your commands here

Setting up public keys to use with SSH (and restrict user to only use Subversion)


When opening a SSH session, you're usually asked a password to authenticate into the remote machine. As explained in an earlier post, you can generate key pairs and use them for authentication. Key pairs also have another advantage: you can provide some users a key pair to authenticate and configure the SSH daemon to restrict their abilities to interact with the system. Specifically, you can setup the remote machine to only allow some users to launch a specific command, svnserve in this case, when authenticating. This is especially useful when you share a repository with users outside your organization. You can create user accounts and key pairs for them: with a proper configuration such users, although listed in your user database (both local files or directories such as LDAP), they will only be able to login and launch the svnserve command in tunnel mode. This approach together with Solaris Zone technology will give you the possibility:

  • To quickly set up zones on your system to host subversion repositories.
  • To optionally centralize your user accounts in the directory of your choice.
  • To limit some user account to only use the Subversion server, effectively prohibiting them to open an interactive login session into your system.
  • You can centralize the setup of the users' home directory by using the Solaris automounter. Subversion-only users will have their homes automounted from an ad-hoc server.

To configure the machine, or the Solaris zone, which hosts the Subversion server, you only have to follow the instructions in this post to provide them a key to connect to the server. Once this is done, if you want to limit your user ability by specifying a command to execute at login, you just have to add this fragment before the public part of the key:

command="/opt/csw/bin/svnserve -t"

In this case I specified svnserve path as installed by the Blastwave's package: if your setup is different, just change the path. If you're using Solaris Express Community Edition or OpenSolaris, Subversion may be found in:

command="/usr/bin/svnserve -t"


Please be aware that this fragment must be inserted before the key fragment and in the same line.

If the number of the users is such that you don't want to manage this process manually, you can for example:

  • Use a script to generate the keys and to concatenate the public part into the authorized_keys2 file.
  • Manage a centralized authorized_keys2 file.
  • Share the authorized_keys2 file amongst users' home directories: they won't be able to read that file.
  • Optionally automount users' home directories to share this configuration in many systems or zones.

Configure your users' groups


As mentioned earlier, users should belong to a group with the necessary permissions (read and write) on the repository directory. If you manage your users with local files, just assign them the proper primary and secondary roles: if you need secondary roles for some users you can use the newgrp command in a wrapper shell script to have an user login into the desired group before invoking the Subversion commands.

If you use a directory service, configure the directory appropriately. If you're using the Sun Java System Directory Server and you're using the default LDAP schema, assigning groups to user is pretty easy:

  • The primary group can be specified setting the gidnumber attribute of the LDAP user entry.
  • The secondary groups can be specified by adding multiple memberuid attributes into the group entry.

To add the users joe and john to a group you just add:

memberuid: joe

memberuid: john

into the group definition.


An alternative configuration with just one subversion user


If you do not want to leverage your existing user repository or you don't even have one, don't worry. In that case, all you have to do is setup your subversion repositories as usual and then manually setup the user for the current tunnel with the --tunnel-user=username option in the authorized_keys files. That's it.

Setting up zones


Setting up sparse zones in Solaris 10 is really straightforward and Sun Solaris 10 official Zones documentation covers the topic with great detail.

If you need to configure the zone to use an LDAP, please refer to the Solaris 10 Naming and Directory Services administration guide.

If you want to follow my advice, you can setup a zone for installing Blastwave's software and share the installation between zone using a loopback mount.

Next steps

You can now:



If some of your users run Windows, you can read the following post to learn how to configure TortoiseSVN to use your public key to connect to Subversion using an SSH-tunneled connection.

Monday, November 3, 2008

Connecting with SSH without typing a password

I'm heavily relying on some remote machines to get some jobs done so SSH is a tool I used daily. The downside of being sit in front of a terminal opening and closing many SSH connections is that you have to type in your password over and over again.

I started looking at SSH documentation hoping to find a way to ease this pain without trading off SSH inherent security. I'm using version 2.0 of the SSH protocol and the solution is authenticating using a key.

The first step is creating RSA private/public keys with a tool which comes with SSH:

$ ssh-keygen -t rsa


ssh-keygen will then produce the following files in the ~/.ssh directory: id_rsa and id_rsa.pub. The complete output of ssh-keygen is the following:

enrico@solaris:~$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/enrico/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/enrico/prova.
Your public key has been saved in /home/enrico/prova.pub.
The key fingerprint is:
23:63:25:1d:2a:0a:34:c8:47:d9:65:80:43:f6:c9:e8 enrico@solaris

Obviously, a good advice would be using a passphrase: please note that in this case SSH will be asking for user input and instead of your password you'll be typing your passphrase. In my case, I decided to use an empty passphrase and keep keys' files safe.

Once you have your keys generated, you have to copy the public key on every server you want to log on to. The content of id_rsa.pub is a line which must be appended to the .ssh/authorized_keys2 file. If this file does not exist, just create it copying id_rsa.pub in .ssh/authorized_keys2. Even if you use a passphrase, care should be taken to protect files in the .ssh directory. At most, this directory and its content should have 0600 permission level.

Now you have setup your environment and the sshd daemon on the server you log in will encrypt communications (2.0 protocol version) using the public key you provided and next time you'll log in via SSH to that server, you won't be asked your password any longer!