Changing displayed hostname in bash prompt based on login credentials

12,968

Solution 1

It turns out that ssh finds lines in ssh_config(5) by string matching, so it's OK if all the IP's are the same.

What you want, then, are

  • Different lines in .ssh/config for each system, use HostName to give ssh the real host domain name
  • Have three different environment variables with different prompts in them in your local environment
  • Have each line in .ssh/config send a different variable using SendEnv, see man ssh_config.
  • Make your prompt out of all three (two will always be null)
  • Put AcceptEnv * in /etc/ssh/sshd_config and sudo kill -1 $(cat /var/run/sshd.pid)
    (AcceptEnv E1 E2 E3 should also work.)

Example.

Client .ssh/config

Host barb
        HostName deb
        SendEnv BARB

Host jane
        HostName deb
        SendEnv JANE

Host deb barb jane
        Protocol 2
        ForwardAgent yes
        Compression no

Server .bashrc

PS1='$BARB$JANE.otherstuff...'

Server /etc/ssh/sshd_config

...
AcceptEnv *

Solution 2

One way to do this could be to make entries for each of your hostnames in your local ~/.ssh/config, configured to connect to different ports on your server.

Host foo
  HostName www.foo.com
  Port 1022

Host bar HostName www.bar.com Port 2022

Then your ~/.bashrc on the server can parse the SSH_CONNECTION environment variable and pick out the port you've connected to, and change the prompt accordingly.

case $(ruby -e 'puts ENV["SSH_CONNECTION"].split[-1]') in
  1022)
    WEBHOST="www.foo.com"
  ;;
  2022)
    WEBHOST="www.bar.com"
  ;;
  *)
    WEBHOST="www.foobar.com"
  ;;
esac

PS1="\n\u@$WEBHOST \w\n$?> "

Obviously you would need ruby in your path for this, but you see what I mean.

Solution 3

You might be able to use the SendEnv directive (protocol 2 is required and sshd on the remote machine must be configured for AcceptEnv to include the name of the variable you want to use):

On the local machine:

export dest=example.com; ssh -o "SendEnv dest" username@$dest

On the remote machine, in ~/.bashrc:

PS1="...${dest}..."

Where the ellipses represent the rest of the stuff in your prompt.

If you edit /etc/ssh/sshd_config to add a variable you may have to send SIGHUP to sshd.

Solution 4

Do your domains all have different IPs?

If so, you can use the variable $SSH_CONNECTION once you are logged in.

If not, then it is impossible to differentiate, all the server sees is the IP address, there is no such thing as name-based ssh.

Share:
12,968

Related videos on Youtube

warren
Author by

warren

I'm a hobbyist programmer, part-time sysadmin, and full-time analytics, big data, data center management, automation, and cloud computing architect and delivery engineer.

Updated on September 17, 2022

Comments

  • warren
    warren over 1 year

    I host several domains on one server.

    I would like to be able to change the displayed hostname in my bash prompt to indicate which one I picked when ssh'ing into the server.

    My prompt is as follows:

    \u@\h
    

    This displays as:

    user@hostname
    

    How would I change the \h to show which domain I had logged-into (blah.net, hmm.com, etc)?

  • warren
    warren over 14 years
    no - all the same IP.. they're fairly low-traffic domains on this server
  • Dennis Williamson
    Dennis Williamson over 14 years
    Or you could do the same thing without ruby using bash: sshconn=($SSH_CONNECTION); case "${sshconn[3]}" in
  • Dennis Williamson
    Dennis Williamson over 14 years
    I would be nervous about AcceptEnv * being a security issue. In any case "don't open what you don't need" applies.
  • Admin
    Admin over 14 years
    nice, cheers :)
  • Admin
    Admin over 14 years
    Dammit I knew there must have been something like SendEnv...one must remember to read manpage before posting :) Great answer.
  • warren
    warren about 13 years
    thanks for that .. but my prompt already does this. the "h" tells the prompt to use the results of hostname in the display. hostname does not change based on which incoming domain name you used, but uses the canonical name of the device