🔒 Accessing git Servers Over Another Port When 22 is Blocked and Cloning Hangs Waiting for Connection#

It’s been awhile since I’ve setup my last work system a year back, so this past month I’ve gone through the usual pains of preparing a new machine. One of those pains was realizing some network segments at one of the libraries I am a regular at have port 22 blocked at an internal boundary. Without falling into discussions about how useful such a thing is from a defensive security point of view, I wanted to share a trick not many folks know of. It turns out that, precisely for those situations, all renowned Git hosting providers offer access to their Git service via an alternative port: 443.

Addendum#

git clone Hanging#

The initial issue arose when I was working locally on a repository I had cloned already and then needed to clone another personal one, let’s assume for the sake of brevity it was jdsalaro/jdsalaro.com.

1$ git clone git@github.com:jdsalaro/jdsalaro.com.git
2Cloning into 'jdsalaro.com'...

As I waited for a couple of seconds I observed git just hanged there without doing much; obviously something was amiss. My usual attempt at debugging didn’t yield much that was of interest as can be seen below:

1$ GIT_TRACE=2 GIT_CURL_VERBOSE=2 GIT_TRACE_PERFORMANCE=2 GIT_TRACE_PACK_ACCESS=2 GIT_TRACE_PACKET=2 GIT_TRACE_PACKFILE=2 GIT_TRACE_SETUP=2 GIT_TRACE_SHALLOW=2 git clone git@github.com:jdsalaro/jdsalaro.com.git 
2
313:12:27.776079 git.c:465               trace: built-in: git clone git@github.com:jdsalaro/jdsalaro.com.git
4Cloning into 'jdsalaro.com'...
513:12:27.781106 run-command.c:657       trace: run_command: unset GIT_DIR; GIT_PROTOCOL=version=2 ssh -o SendEnv=GIT_PROTOCOL git@github.com 'git-upload-pack '\''jdsalaro/jdsalaro.com.git'\'''

Similarly, ssh failed to establish a connection to the server at all for both github.com and gitlab.com; bitbucket.org, cloud.gitea.com and codeberg.org would have failed as well.

1$ ssh -T git@github.com
2
3^C
4$ ssh -T git@gitlab.com
5
6^C
7$ 

Nevertheless, ssh’s debug output was much more useful in this case:

 1$ ssh -T git@github.com -vvv
 2OpenSSH_9.6p1, LibreSSL 3.3.6
 3debug1: Reading configuration data /Users/[...]/.ssh/config
 4debug1: Reading configuration data /etc/ssh/ssh_config
 5debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/* matched no files
 6debug1: /etc/ssh/ssh_config line 54: Applying options for *
 7debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts' -> '/Users/[...]/.ssh/known_hosts'
 8debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts2' -> '/Users/[...]/.ssh/known_hosts2'
 9debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
10debug3: channel_clear_timeouts: clearing
11debug1: Connecting to github.com port 22.

It Wasn’t a Me Problem#

The connection wasn’t even being established, but internet connectivity wasn’t an issue:

1curl example.com | grep title
2  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
3                                 Dload  Upload   Total   Spent    Left  Speed
4100  1256  100  1256    0     0   6372      0 --:--:-- --:--:-- --:--:--  6408
5    <title>Example Domain</title>

And the corresponding providers were available over HTTPS and weren’t reporting an outage:

1$ nc github.com 443
2AAAA

The network connection looked alright on the wire, should I say waves?, as well:

For port 443 the whole TCP/IP spiel was taking place as expected: SYN followed by SYNACK, ACK and data being transferred. At that point it became obvious that someone had made the decision in the past days to start restricting outbound connections to port 22:

1$ nc github.com 22 
2^C
3$ 

A quick Wireshark capture showed as much; outbound TCP handshakes to port 22 weren’t taking place:

The Solution#

As mentioned in my brief introduction for this post, most Git hosting providers will also offer their service over HTTPS [1][2][3].

Addressing the issue described here is just a matter of configuring the respective hostnames to their respective alternatives:

 1$ cat ~/.ssh/config
 2
 3Host github.com
 4  Hostname ssh.github.com
 5  Port 443
 6  User git
 7  PreferredAuthentications publickey
 8  IdentityFile ~/.ssh/github
 9
10Host gitlab.com
11  Hostname altssh.gitlab.com
12  Port 443
13  User git
14  PreferredAuthentications publickey
15  IdentityFile ~/.ssh/gitlab

Et voilà, we’re back online:

$ ssh -T git@github.com

Hi jdsalaro! You've successfully authenticated, but GitHub does not provide shell access.

$ ssh -T git@gitlab.com

Welcome to GitLab, @jdsalaro!

Final Words#

Hope y’all found this brief debugging session interesting, it’s a bit over-engineered in order to make it interesting and blog-worthy, but is not too far detached from how I’d approach similar problems in reality.

Stay in touch by entering your email below and receive updates whenever I post something new:

As always, thank you for reading and remember that feedback is welcome and appreciated; you may contact me via email or social media. Let me know if there's anything else you'd like to know, something you'd like to have corrected, translated, added or clarified further.

Footnotes#