Sat 31 May 2025 in ssh by Regalis
How to update an offline GNU/Linux system using SSH?
Introduction
Throughout my many years in business, I have constantly encountered servers connected to the Internet... Although it is not necessary. Keeping your server offline is one of the most effective ways to avoid serious security issues such as data leaks and remote takeovers.
What is the most common reason for connecting servers to the Internet? Well, the most common reason I hear is "I have to update it somehow."
There are a few ways to update offline servers very conveniently. Today I'll
show you how to do it very easily using ssh
. It's not the optimal technique for
many servers, but you might find it useful.
A more efficient method for updating multiple hosts is described in my other article about why you should keep most of your infrastructure offline.
Basic idea
Let's say we have the following infrastructure:
In this configuration, your destination host (Debian GNU/Linux) has no access
to the Internet, so you won't be able to run apt update && apt upgrade
.
SSH reverse socks proxy
You can use your SSH client to act as a socks proxy
and simply perform a
remote port forwarding
to this proxy. Remote port forwarding works in the way
that connections to the given TCP port or Unix socket on the remote (server)
host are to be forwarded to the local side. This way, your destination
host will be able to use your machine to access the official Debian GNU/Linux
repositories.
And you can do this by using a single SSH option: -R
.
As you can see, it works even if you have a jumphost
on your way.
Verify your connection
Normally, if you just connect to your offline host and use curl
, you should
expect something like this:
1 2 3 4 |
|
This will be exactly the same if you use -R9999
:
1 2 3 4 |
|
This is because you need to tell the curl
to use your socks proxy
, you can
do this with a simple environment variable called ALL_PROXY
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Names resolution - socks5h:// vs socks5://
Did you notice socks5h://
or --socks5-hostname
? Use this if you want
your host/program to resolve hostnames using SOCKS Proxy instead of
system-configured DNS servers. Since your system is offline, it won't be
able to resolve domain names on its own.
Upgrade your system using apt
How to tell apt
to use your reverse socks proxy?
1 2 3 4 5 6 7 |
|
How to persist apt
's proxy configuration?
Just put a line Acquire::http::proxy "socks5h://localhost:9999;"
inside your configuration file, for example /etc/apt/apt.conf.d/99-ssh-socks-proxy.conf
:
1 2 3 4 5 6 7 8 |
|
Filter your socks proxy connections
SSH client has an option called PermitRemoteOpen
, you can use it to filter
connections. For example, you can allow only deb.debian.org:443
and
security.debian.org:443
using:
1 2 3 4 5 6 7 8 |
|
As you can see, connection to regalis.tech:443
was blocked, but apt
is still happy!
Of course, you can use your SSH config file (on the client side) to write down all these options and make a very easy to use shortcut. You can even update and upgrade remote, offline host with a single line, including jumping over the jumphost
:
1 2 3 4 5 6 7 |
|
I described the ssh configuration in a previous post.
Summary
SSH is an incredibly powerful tool, and many administrators are not fully aware of its capabilities. A key takeaway from this post should also be security - please pay attention to the following points:
- if you allow remote port forwarding in
sshd
, any SSH client can use the technique described above to exfiltrate data or sneak Internet access, - connections established using this method will not be visible on the firewall,
- even if your system is offline but SSH is enabled, anyone can exploit
RemoteForward
.
And as always, remember: When it comes to cybersecurity - no magic security tool, no matter how or by whom it's marketed, can replace good design, knowledge, and experience. Know your tools!
Happy hacking! (and remove your PuTTY 😉)