git using a custom ssh port

Questions

When you have deployed your own gitlab service on web, you may need to use a custom SSH port to clone, pull, or push your code from or to your server. The default SSH port 22 is used by the system SSH service, so you must choose another port for your gitlab service.

After you get everything done, you may find that you can’t clone your repository because of the access error. If you check carefully, you will find that the default git url is scp-like syntax. You can’t change port to your custom SSH port.

git clone user@hostname:/path/to/repo.git
output

ssh: connect to host [hostname] port 22: Connection timed out
fatal: Could not read from remmote repository.

Please make sure you have the correct access rights and the repository exists.

Solutions

Using Standard SSH syntax

The scp-like syntax separate the hostname and path with a colon, so we can’t use colon to define a custom port. The Standard SSH syntax solve this problem:

git clone ssh://[user@]hostname[:port]/path/to/repo.git

Using scp-like syntax

The url you copy from github or gitlab is always in scp-like syntax. Transforming it from scp-like syntax to standard SSH syntax, which is a little bit complicated when using. Can we still use scp-like syntax, but change the default SSH port to our custom port?

Definitely sure. Just edit the SSH config file (on Windows):

  1. Find the .ssh directory. always in C:\\Users\\[username]\\.ssh\\;

  2. Edit config file, add your gitlab host config (Don’t add square brackets in your config);

    # your host config name (always the same as your hostname)
    Host [your_gitlab_host]
      # your ssh hostname
      HostName [your_gitlab_hostname]
      Port [your_gitlab_custom_ssh_port]
      User [your_gitlab_user_name]
      # use public key for authentication instead of the username and password
      PreferredAuthentications publickey
      # private key path for this host (always in you .ssh directory)
      IdentityFile C:\\Users\\[username]\\.ssh\\[your_ssh_key]

    If you don’t need an independent IdentityFile for your gitlab, you may delete the line of IdentityFile, the SSH connection will use default key named id_rsa which you generated by default.

  3. Save and use scp-like syntax directly;

Extra Information

Git URLs

In general, URLs contain information about the transport protocol, the address of the remote server, and the path to the repository. Depending on the transport protocol, some of this information may be absent.

Git supports ssh, git, http, and https protocols (in addition, ftp, and ftps can be used for fetching, but this is inefficient and deprecated; do not use it).

The native transport (i.e. git:// URL) does no authentication and should be used with caution on unsecured networks.

The following syntaxes may be used with them:

  • ssh://[user@]hostname[:port]/path/to/repo.git

  • git://hostname[:port]/path/to/repo.git

  • http[s]://hostname[:port]/path/to/repo.git

  • ftp[s]://hostname[:port]/path/to/repo.git

An alternative scp-like syntax may also be used with the ssh protocol:

  • [user@]hostname:path/to/repo.git

This syntax is only recognized if there are no slashes before the first colon. This helps differentiate a local path that contains a colon. For example the local path foo:bar could be specified as an absolute path or ./foo:bar to avoid being misinterpreted as an ssh url.

The ssh and git protocols additionally support ~username expansion:

  • ssh://[user@]hostname[:port]/~[user]/path/to/repo.git/

  • git://hostname[:port]/~[user]/path/to/repo.git/

  • [user@]hostname:/~[user]/path/to/repo.git/

For local repositories, also supported by Git natively, the following syntaxes may be used:

  • /path/to/repo.git/

  • file:///path/to/repo.git/

These two syntaxes are mostly equivalent, except the former implies –local option.

The Git Protocols

Git can use four distinct protocols to transfer data: Local, HTTP, Secure Shell (SSH), and Git.

Local Protocol

The most basic is the Local protocol, in which the remote repository is in another directory on the same host. This is often used if everyone on your team has access to a shared filesystem such as an NFS mount, or in the less likely case that everyone logs in to the same computer.

git clone /path/to/repo.git
git clone file://path/to/repo.git

Git operates slightly differently if you explicitly specify file:// at the beginning of the URL. If you just specify the path, Git tries to use hardlinks or directly copy the files it needs. If you specify file://, Git fires up the processes that it normally uses to transfer data over a network, which is generally much less efficient. The main reason to specify the file:// prefix is if you want a clean copy of the repository with extraneous references or objects left out - generally after an import from another VCS or something similar. We’ll use the normal path here because doing so is almost always faster.

The HTTP Protocol

Git can communicate over HTTP using two different modes. Prior to Git 1.6.6, there was only one way it could do this which was very simple and generally read-only. In version 1.6.6, a new, smarter protocol was introduced that involved Git being able to intelligently negotiate data transfer in a manner similar to how it does over SSH.

Smart HTTP operates very similarly to the SSH or Git protocols but runs over standard HTTPS ports and can use various HTTP authentication mechanisms, meaning it’s often easier on the user than something like SSH, since you can use things like username/password authentication rather than having to set up SSH keys.

git clone https://hostname/path/to/repo.git

The SSH Protocol

A common transport protocol for Git when self-hosting is over SSH. This is because SSH access to servers is already set up in most places — and if it isn’t, it’s easy to do. SSH is also an authenticated network protocol and, because it’s ubiquitous, it’s generally easy to set up and use.

To clone a Git repository over SSH, you can specify an ssh:// URL like this:

git clone ssh://[user@]hostname[:port]/path/to/repo.git

Or you can use the shorter scp-like syntax for the SSH protocol:

git clone [user@]hostname:path/to/repo.git

The scp-like syntax uses colon to separate hostname and path, so we can’t specify port with this syntax if we don’t edit SSH config file.

The Git Protocol

Finally, we have the Git protocol. This is a special daemon that comes packaged with Git; it listens on a dedicated port (9418) that provides a service similar to the SSH protocol, but with absolutely no authentication. In order for a repository to be served over the Git protocol, you must create a git-daemon-export-ok file — the daemon won’t serve a repository without that file in it — but, other than that, there is no security. Either the Git repository is available for everyone to clone, or it isn’t. This means that there is generally no pushing over this protocol. You can enable push access but, given the lack of authentication, anyone on the internet who finds your project’s URL could push to that project. Suffice it to say that this is rare.

References

Git on custom SSH port

git-clone

Git on the Server - The Protocols