Recently at work I've had to figure out how to get apt
to work on a Linux box that doesn't have any Internet connectivity itself, but is connected to another Linux box that's working just fine. I decided to head home that day and first mock up my approach using Vagrant, since this is probably knowledge I will want to be able to reference later on as well.
Clone this repo, then use
vagrant up
to get these VMs working. If you run
# From your local box
vagrant ssh internet_server
# From within internet_server - password is `vagrant`
ssh [email protected]
# From within internal_server, from within internet_server - password is, again, `vagrant`
ssh [email protected]
you should be able to SSH from internet_server
to internal_server
. Then the fun begins...
... If you
# From within internet_server
ssh [email protected] "ping -c 3 8.8.8.8"
# Should return 3 normal pings.
you will see that internal_server
can still very much reach the Internet. We do not want this. So we are going to shut this down, with
# From within internet_server
ssh [email protected] "sudo ip link set dev eth0 down"
sleep 10
# The confirm you can still SSH in as per usual, even though you've just eviscerated an Ethernet interface.
ssh [email protected] "ip a"
Finally, run
# From within internet_server
ssh [email protected] "ping -c 3 8.8.8.8"
# Should return NOTHING. NOTHING AT ALL
to ensure all is lost.
Let's just make sure we can't access the thing we care about here, one more time:
# From within internet_server
sudo apt update
# should work fine
ssh [email protected]
# From within internal_server
sudo apt update
# should fail
# From within internet_server
ssh [email protected]
# From within internal_server
ssh -D 1080 [email protected]
# Leave this running!
Now open another terminal window. Do not close out of the one running ssh -D
!
# From your bare metal box
vagrant ssh internet_server
# From within internet_server
ssh [email protected]
# From within internal_server
curl --socks5 localhost:1080 https://1.1.1.1
# Should return a bunch of HTML!
Excellent! We have proven we can reach the outer web via a SOCK5 proxy.
Now for the next question: How do we get DNS hostnames to resolve too?
It turns out we don't have to change much. We can just do
# From within internal_server
curl --socks5-hostname localhost:1080 https://example.com
Easy peasy. Will apt
, however, be so simple?
Unfortunately not. But there is a dependency-less program called tsocks
which can help us out!
# On internet_server
curl -o tsocks.deb https://http.us.debian.org/debian/pool/main/t/tsocks/tsocks_1.8beta5+ds1-1_amd64.deb
sftp [email protected]
# In the SFTP shell
put tsocks.deb
exit
# Back on internet_server
ssh [email protected]
# On internal_server
sudo dpkg -i tsocks.deb
tsocks
should now be installed. You can check this with
which tsocks
# /usr/bin/tsocks for me
Now we need to configure it. Open /etc/tsocks.conf
in your favorite web editor, and change the following lines:
server = 192.168.56.2 # The IP of internet_server
server_port = 1080 # The port you used for your SOCKS5 proxy
Then run
# From within internal_server
. tsocks on # to make sure tsocks is working
tsocks show # you should something like "LD_PRELOAD="libtsocks.so""
curl https://1.1.1.1 # should give some HTML, rather than nothing
curl https://5.9.243.187 # alternative if 1.1.1.1 is acting weird, leads to wttr.in
TODO: Compile tsocks and turn on DNS forcing ourselves!
- In order to SOCKS5 proxy correctly, your
internet_server
and yourinternal_server
must form an SSH cycle somewhere --internet_server
must be able to reachinternal_server
and vice versa. Ask yourself: Could I SSH back to where I started without ever exiting an earlier SSH session?