3 ways to use apt in a private server

In this post, I will show 3 ways to use apt in a private server (a server that does not have direct internet access).

Method 1: Download the .deb files and install them manually

Adding  --print-uris to the apt command will print the URLs to download necessary .deb files. You can download the .deb files, place them on the server and install them with the dpkg -i <downloaded deb file>.deb.

# apt install --print-uris build-essential
ubuntu@ip-10-10-142-139:~$ sudo apt-get install --print-uris build-essential
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  bzip2 cpp cpp-11 dpkg-dev fakeroot fontconfig-config fonts-dejavu-core g++
  g++-11 gcc gcc-11 gcc-11-base libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan6 libatomic1
  libc-dev-bin libc-devtools libc6-dev libcc1-0 libcrypt-dev libdeflate0
  libdpkg-perl libfakeroot libfile-fcntllock-perl libfontconfig1 libgcc-11-dev
  libgd3 libgomp1 libisl23 libitm1 libjbig0 libjpeg-turbo8 libjpeg8 liblsan0
  libmpc3 libnsl-dev libquadmath0 libstdc++-11-dev libtiff5 libtirpc-dev
  libtsan0 libubsan1 libwebp7 libxpm4 linux-libc-dev lto-disabled-list make
  manpages-dev rpcsvc-proto
Suggested packages:
  bzip2-doc cpp-doc gcc-11-locales debian-keyring g++-multilib g++-11-multilib
  gcc-11-doc gcc-multilib autoconf automake libtool flex bison gdb gcc-doc
  gcc-11-multilib glibc-doc bzr libgd-tools libstdc++-11-doc make-doc
The following NEW packages will be installed:
  build-essential bzip2 cpp cpp-11 dpkg-dev fakeroot fontconfig-config
  fonts-dejavu-core g++ g++-11 gcc gcc-11 gcc-11-base libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan6 libatomic1
  libc-dev-bin libc-devtools libc6-dev libcc1-0 libcrypt-dev libdeflate0
  libdpkg-perl libfakeroot libfile-fcntllock-perl libfontconfig1 libgcc-11-dev
  libgd3 libgomp1 libisl23 libitm1 libjbig0 libjpeg-turbo8 libjpeg8 liblsan0
  libmpc3 libnsl-dev libquadmath0 libstdc++-11-dev libtiff5 libtirpc-dev
  libtsan0 libubsan1 libwebp7 libxpm4 linux-libc-dev lto-disabled-list make
  manpages-dev rpcsvc-proto
0 upgraded, 52 newly installed, 0 to remove and 0 not upgraded.
Need to get 63.6 MB of archives.
After this operation, 207 MB of additional disk space will be used.
'http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu/pool/main/g/glibc/libc-dev-bin_2.35-0ubuntu3_amd64.deb' libc-dev-bin_2.35-0ubuntu3_amd64.deb 20334 MD5Sum:96b017626d9be3b8d05ebef8c71d978a
'http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu/pool/main/l/linux/linux-libc-dev_5.15.0-37.39_amd64.deb' linux-libc-dev_5.15.0-37.39_amd64.deb 1313386 MD5Sum:ea4648da5d6bc50f2120dc0960051d5a
[output truncated]

Condition: you have a client with internet access that can ssh to the private server.

Step 1 (optional): Firstly, you need to determine the server domain that apt uses using method 1. For example, in the sample output:

'http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu/pool/main/l/linux/linux-libc-dev_5.15.0-37.39_amd64.deb' linux-libc-dev_5.15.0-37.39_amd64.deb 1313386 MD5Sum:ea4648da5d6bc50f2120dc0960051d5a

We get the domain ap-northeast-1.ec2.archive.ubuntu.com. You can skip this step and use any domain, for example us.archive.ubuntu.com. However, it may not be as performant as the one outputted by the command line.

Step 2: Next, from the client, open an ssh reverse tunnel to the private server by running (from the client):

ssh -R 2222:ap-northeast-1.ec2.archive.ubuntu.com:80 transang@1.2.3.4 -NT
ssh -R <any port>:<apt domain>:80 <username>@<private server IP>

Where,

  • 2222 is an arbitrary (available) port on the private server.
  • ap-northeast-1.ec2.archive.ubuntu.com is the apt domain found in step 1.
  • transang@1.2.3.4 is the private server address.
  • -NT are optional ssh command's flags to prevent ssh from allocating a new pseudo-terminal and executing any command.

Step 3: config apt to use the ssh tunnel as its proxy.

Edit /etc/apt/apt.conf, include the following lines

Acquire::http::Proxy "http://localhost:2222";
Acquire::https::Proxy "https://localhost:2222";
You should change the 2222 port according to the port used in step 2

Now you can use apt like there is direct internet access. The config in step 3 tells apt to forward all download requests to localhost:2222, which will be proxied to ap-northeast-1.ec2.archive.ubuntu.com:80 accessed from the client.

Method 3: use sock proxy (not tested)

Condition: the private server can ssh to another server that has internet access.

Step 1: Open a local sock proxy by running the following command at the private server

ssh -D 2222 -NT transang@4.3.2.1
`ssh -D <any port> -NT <username>@<the another server>

Where,

  • 2222 is an arbitrary (available) port on the private server
  • transang@4.3.2.1 is the address of another server with internet access that can be sshed from the private server.

Step 2: configure apt to use the local sock proxy

Edit /etc/apt/apt.conf, include the following line:

Acquire::socks::proxy "socks://localhost:2222/";

Now, you can use apt, all download requests are executed through the configured proxy that will be accessed through the 4.3.2.1 server.