How to connect to Android through SSH over 3G/4G public IP? I am having an Android device and I want to connect in via 3G/4G and I am getting connection refused.

Any ideas how to do that?
If you have a working SSH server running on Android device, you can connect to it on local/private network without any issues (after proper authentication setup obviously). Same may hold true for public network (internet) if your phone has a true public IP address (I don't think that happens on earth). However, when you need to cross networks i.e. traversing gateways and routers, there is Network Address Translation involved. You won't be able to access your device from internet if your SSH server can't be exposed to a public IP address.  



WHAT IS NAT AND PAT?
In simple words, NAT is the translation of source IP from private address to public - routable; what they call it - address when an IP packet is leaving the router, so that packet could be sent back with identifiable IP address. Inverse happens when response for same packet is received back at router. It would mean mapping private IP of every host (phone, PC etc.) on local network to a unique public IP. But in usual cases, we just have one public IP assigned by ISP. So Port Address Translation comes in action. PAT translates every local IP address to same public IP address but with a unique port.

WHAT IS CGNAT?
To address the problem of IP Address Shortage, Internet Service Providers also perform NAT, called Carrier Grade NAT. It means that IP address assigned by ISP to you isn't either a public but private IP address. This is a definite situation with Mobile Data i.e. on 3G/4G but less common with DSL connections.
If the IP assigned to your phone by ISP (you can check by ip address | grep inet command) is different from the one shown here, you are behind a CGNAT. Similarly for Wi-Fi router, IP address appearing under PPP Connection Settings should match with the public IP.

DYNAMIC IP ADDRESS:
In order to maximum utilize the available pool of IP addresses, ISP's mostly assign dynamic IP address even when there is no CGNAT. So the public IP keeps on changing on daily, weekly, monthly or randomly basis, depending on the ISP's policy.



IPv6 is the upcoming protocol which won't need NAT and every network host on earth would be able to have a unique IP address.



SOLUTION:
Now coming to your question:


If there is no CGNAT, we can tackle the problem of DSL/3G/4G router's NAT by setting up Port Forwarding. But this option doesn't work if:


There is more than one hosts on local network that listen on same port (22 in case of ssh).
ISP firewalls don't allow you to receive incoming connections.
ISP locks you out of your router's Port Forwarding section or a 3G/4G router doesn't have a Port Forwarding settings at all.

Problem of Dynamic IP can be worked around by signing up a DDNS service. It assigns you a domain name that always resolves to your current public IP. DynuDNS is a free service that works perfect for me. You will have to install their software on your phone or PC to keep them updated of your public IP.
As far as CGNAT is concerned:


You can opt to buy a static public IP if your ISP provides this service but the price isn't "hearing friendly" in most cases.
Sign up for a service that lets you configure Port Forwarding on public VPN. There are free (for one port forwarding) solutions like portmap.io as well if you are not afraid of your traffic being sniffed :) Another specialized solution is ngrok that uses HTTP, TLS and TCP tunnels.
Setup a SSH (slower) or VPN (faster) tunnel from your phone to a personal server.


For best security and privacy, setup a self-owned server. You may use your broadband connection (if that has a public IP) for this purpose or may ask some friend to offer you this service.
Buy some trustworthy cloud VPS solution like AWS to host your personal SSH/VPN server. Setup is a bit technical but guides (1, 2) are available.






If you go with last option (setup a personal SSH or VPN server with public/static/dedicated IP address), follow the steps below to forward a specific port from SSH/VPN server to your phone:


SSH:

With an SSH server setup, you can create Reverse Port Forwarding tunnel from your phone. Note that you can't forward remote server's (default SSH) port 22 to your phone's port 22 if you are connecting to the server on same port.  

Make sure GatewayPorts yes and AllowTcpForwarding yes are set in sshd_config on server, so that sshd allows port forwarding and accepts connections from public. Now on your phone create a reverse tunnel:

~$ ssh -NTR 2222:localhost:22 &lt;server_user&gt;@&lt;server_ip&gt;


You can make ssh tunnel persistent using autossh or some app like ConnectBot if you want.

For further options see this answer.
VPN:

From your phone connect to the VPN server using a VPN app. When on a Virtual Private Network (VPN), both server and phone become part of a local network, so just apply iptables DNAT to forward the specific port to your phone's IP:

~# iptables -t nat -I PREROUTING -p tcp --dport 2222 -j DNAT --to &lt;phone_ip&gt;:22


IP Forwarding is also required on server, which has probably been already set up during VPN server configuration:

~# echo 1 &gt;/proc/sys/net/ipv4/ip_forward
~# iptables -I FORWARD -d &lt;phone_ip&gt; -j ACCEPT
~# iptables -I FORWARD -s &lt;phone_ip&gt; -j ACCEPT



Now you can ssh from any host on internet to your phone:

~$ ssh &lt;phone_user&gt;@&lt;server_ip&gt; -p 2222


You'll be logged in to your phone after authentication.



I explained here the SSH example. In the same way you can run any other server on your phone and forward its port from SSH/VPN server (with public IP) to your phone (with no public IP) so that your server becomes accessible from internet.



RELATED:


How to run SSH/SFTP server for multiple user logins with password authentication on Android?
How to connect two phones via SSH?