Mastering ssh-tunnels

Add this to ~/.zshrc or ~/.bashrc and be happy =):


# By saying PROXY I mean it is a host located in internal network.
# You can access any other internal hosts from it via SSH.

# Export some variables
export PROXY_KEY_PATH="~/.ssh/proxy/id_rsa" # path to locally stored private key from PROXY-server
export PROXY_USER="user" # user name to get access to PROXY via SSH
export PROXY_HOST="internal.host.foobar.com" # FQDN or IP of a proxy
export PROXY_AUTH="$PROXY_USER@$PROXY_HOST" # literally it is a string "user@internal.host.foobar.com"

# Connect to PROXY via SSH
alias proxy="ssh $PROXY_AUTH"

# Connect to PROXY via SSH and attach to screen (P.S. don't do it inside a locally launched screen :))
alias proxy_screen="ssh -t $PROXY_AUTH screen -x"

# Forward some service's port which you can access only from PROXY to localhost:1234
# 1234 - local port with service
# ServiceHost - IP-address of a host with service
# ServicePort - Port of a service at ServiceHost
alias tunnel_service='ssh -L 1234:ServiceHost:ServicePort $PROXY_AUTH'

# Forward MySQL-connection which you can access only from some host inside enterprise network (no a PROXY-host) to localhost
# MySQLHost - IP-address of MySQL-server
# WebHost - IP-address of a host that can connect to MySQLHost
# WebUser - User name to access from PROXY to WebHost via SSH
alias tunnel_mysql='ssh -A -i $PROXY_KEY_PATH -L 3306:MySQLHost:3306 -o ProxyCommand="ssh $PROXY_AUTH nc WebHost 22" WebUser@WebHost'

# Run some command at remote server and disconnect
# TargetHost -IP-address of a host where you wanna execute your command
# TargetUser - User name to access from PROXY to TargetHost via SSH
# 'cd /srv/some/directory/; ls -al | wc -l)' - the command you are willing to run
alias remote_directory_count="ssh -i $PROXY_KEY_PATH -t -o ProxyCommand='ssh $PROXY_AUTH nc TargetHost 22' TargetUser@TargetHost 'cd /srv/some/directory/; ls -al | wc -l)'"

Deploy website via Git

On your server

~/www$ git init
Initialized empty Git repository in /home/example.com/www/.git/

Enable current branch rewrite, cause with are using non-bare repo:

~/www$ git config receive.denyCurrentBranch ignore

Create hook .git/hooks/post-receive and write into it:

#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard

Make your hook executive:

~/www$ chmod +x .git/hooks/post-receive

On developer machine

Create repo, add all needed files to it, make your first commit.

git init
git config --local user.name "Developer Name"
git config --local user.email "developer@company.com"
git add <some_files>
git commit -m 'initial commit'

Now add remote repository as origin:

git remote add origin user@example.com:~/www/
git push --set-upstream origin master

How to work with repository?

After you have changed some files you should add them to commit and send this commit to repository.

git commit -am 'some commit message describes accepted changes'
git push

Security

Make sure that your .htaccess file blocks access to .git/ and .gitignore. To prevent access put the following lines to your .htaccess:

# Prevents access to dot files (.git, .htaccess) - security.
RewriteCond %{SCRIPT_FILENAME} -d
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]

What if I change files directly on server?

All uncommited file changes on server will be ignored after git push from developer machine. If you still want to change files directly on server you should use another two hooks:
.git/hooks/pre-receive

#!/bin/sh
cd ..
GIT_DIR='.git'
git stash save --quiet
git stash show || true

.git/hooks/post-receive

#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard
git stash pop --quiet || git reset --hard

Update kernel on Ubuntu

To update your kernel version run the following commands in your terminal:

sudo add-apt-repository ppa:kernel-ppa/ppa
sudo apt-get update
apt-cache showpkg linux-headers

You will see the list of available kernels. Choose the kernel version you want and run:

sudo apt-get install linux-headers-3.8.0-26 linux-headers-3.8.0-26-generic linux-image-3.8.0-26-generic --fix-missing

Enter ssh password once

Everytime you establish ssh-connection or use git via ssh you will be asked for a password. I suggest to you a simple solution of that issue. Before connecting to remote machine run the following commands in your terminal:

ssh-agent bash
ssh-add /home/$USER/.ssh/id_rsa