总结

总结

我有一台 Linux 计算机,但没有可用的互联网连接。我还有一台未 root 的 Android 设备,该设备有互联网连接和 USB 线将其连接到计算机。如果无法使用普通网络共享,我该如何与 Linux 机器共享 Android 的互联网连接?

答案1

总结

创建到虚拟网络接口的默认路由,然后通过转发端口一起使用,redsocks将Android 设备上的 SSH 服务器视为 Socks5 代理。ssh -Dadb

概述

从高层次来看,不用担心技术上过于精确,你想要的最终沟通结构是这样的:

程序 ↔ iptablesredsockssshadbsshd↔ 互联网

因此,例如,当 Linux 计算机上的程序生成一些传出网络流量时,它会正常发送该流量,但iptables规则会拦截该传出流量并将其传送到redsocksredsocks将该流量转换为 Socks5 代理的消息并通过 SSH 隧道发送它们。 SSH 连接反过来位于通过 USB 连接转发的端口上adb。 在 Android 端,SSH 服务器(例如dropbear通过 SimpleSSHD)充当 Socks5 服务器并将流量发送到互联网上。 传入流量的过程类似,但顺序相反。

选择

作为此设置的一部分,您将需要选择四个端口号,所有端口号都应为非特权端口(1024或更高),并且尚未在您的 Linux 机器上使用:

  • 本地端口redsocks(对于这些说明,我使用默认端口12345
  • DNSredsocks端口(对于这些说明,我使用默认端口5300
  • 隧道 Socks5 端口(对于这些说明,我使用一个常见的选择,8123
  • SSH 端口(对于这些说明,我使用 SimpleSSHD 的默认端口2222

您还需要选择一个您的 Android 可以访问的 DNS 服务器(对于这些说明,我将使用非常流行的8.8.8.8)和一个分配给您的 Linux 机器的 IP 地址,最好是一个 NAT 地址以避免冲突(我将使用192.168.123.123)。

如果您为 Linux 机器选择了不同的端口号、不同的 DNS 服务器和/或不同的 IP 地址,只需按照以下说明替换这些值即可。

Android 设置

如果尚未启用,启用 USB 调试在您的 Android 设备上。

从 Play Store 或您获取应用程序的任何其他位置,安装支持 Socks5 的 SSH 服务器,该服务器可以配置为监听非特权端口(因此不需要 root 访问权限)。请谨慎选择应用程序,记住恶意应用程序可以像任何网络共享应用程序一样查看和操纵您的网络流量。在这些说明中,我将使用简单SSHD,它是免费的,具有所有必需的功能,总体来说非常好用。但是,需要说明的是,我无法保证它的安全性。

打开应用程序并配置您的 SSH 服务器,确保它监听您上面选择的非特权 SSH 端口,并且(如果适用)期望您在 Linux 机器上使用的用户名。在撰写本文时,如果您使用端口,SimpleSSHD 具有适当的默认设置2222

Linux 机器软件安装

如果你的 Linux 电脑上还没有adb,请在你的 Android 上打开浏览器,然后导航至Android SDK 平台工具的下载页面。单击链接下载适用于 Linux 的平台工具,并在提示时阅读并同意许可证。

通过 USB 数据线将 Android 设备连接到 Linux 机器,将下载的存档传输到 Linux 机器,然后将平台工具解压到方便的文件夹中。确保 Android 已解锁并运行命令

/.../platform-tools/adb devices

/.../platform-tools/adb下载的完整路径在哪里adb。如果您之前没有从 Linux 计算机连接到 Android adb,Android 设备将要求您授予访问权限并提供记住 Linux 计算机。选中复选框以记住计算机并授予访问权限。现在记住计算机是必要的,因为下面的脚本需要即时访问,并且不会等待您每次连接时手动授予权限。

在您的 Linux 机器上,尝试(虽然知道会失败)使用您常用的包管理器安装发行版的redsocks包。例如:

sudo apt install redsocks

该命令将出错,因为包管理器无法访问互联网,但它应该会打印出它尝试下载的包的 URL。在 Android 上的网络浏览器中访问每个 URL 以下载包,并将其传输到 Linux 机器。然后,在 Linux 机器上,按照错误消息中列出的顺序打开并安装它们。

完全透明代理设置

安装软件包后,编辑系统redsocks配置,通常位于/etc/redsocks.conf并由 拥有root。(此处的更改假设您尚未将其用于redsocks其他用途。如果是,那么我假设您知道自己在做什么,并且可以适当调整以下所有说明。)在 部分中base,默认设置应该足够了。在单独的redsocks部分中,确保您具有以下设置(但使用您选择的端口号),并且所有其他设置都已注释掉:

local_ip = 127.0.0.1;
local_port = 12345;
ip = 127.0.0.1;
port = 8123;
type = socks5;

类似地,在单独的redudp部分中,确保您具有以下设置(包含您选择的端口号和 DNS 服务器)并且所有其他设置都已被注释掉:

local_ip = 127.0.0.1;
local_port = 12345;
ip = 127.0.0.1;
port = 8123;
dest_ip = 8.8.8.8;
dest_port = 53;
udp_timeout = 30;
udp_timeout_stream = 180;

重新启动 Linux 机器以应用这些更改。

现在创建一个包含以下文本的 Bash 脚本。将第 7 行引用的路径更改为您下载的 的完整路径adb,并记得替换您选择的端口号、DNS 服务器和 Linux 计算机 IP。此外,此脚本假定您正在使用网络管理器,因此如果您没有使用,请将命令替换nmcli为您的计算机的适当等效命令。

#! /usr/bin/env bash

# Tell Bash to exit immediately if any error occurs.
set -e

# Set the full path to adb.
export ADB='/.../platform-tools/adb'

echo 'Connecting to Android device.'

# Ensure that any previous ADB server is stopped.
"$ADB" kill-server

# Start a new ADB server and connect to any devices attached by USB.
"$ADB" devices

# Forward the SSH port, port 2222.
"$ADB" forward tcp:2222 tcp:2222

echo 'Configuring network (administrator password required).'

# Ensure that the kernel will let us create a dummy network interface.
# (We use a dummy network interface to convince Linux that it has an internet
# connection; otherwise it will not even try to send out network traffic.)
sudo modprobe dummy

# Create a dummy network interface if it does not already exist.
ip link show redsocks || (sudo ip link add redsocks type dummy && echo 'Created device "redsocks".')

# Assign an IP address to the dummy network interface if it does not already
# have one.
[ -n "$(ip addr show label redsocks:0)" ] || sudo ip addr add 192.168.123.123/24 brd + dev redsocks label redsocks:0

# Bring up the connection.
nmcli connection up redsocks

# Set a DNS server for the connection.
nmcli connection modify redsocks ipv4.dns 8.8.8.8

# Make the connection the default route if there is not already a default.
[ -n "$(ip route show default)" ] || sudo ip route add default via 192.168.100.1 dev redsocks

# Save the current packet filter rules so that we can restore them later.
IPTABLES_SAVE=$(mktemp)
sudo iptables-save > "$IPTABLES_SAVE"

# Clean out any existing jumps to a REDSOCKS chain.
sudo iptables -t nat -D OUTPUT -p udp -j REDSOCKS >& /dev/null || true
sudo iptables -t nat -D OUTPUT -p tcp -j REDSOCKS >& /dev/null || true

# Clean out any existing REDSOCKS chain.
sudo iptables -t nat -F REDSOCKS >& /dev/null || true
sudo iptables -t nat -X REDSOCKS >& /dev/null || true

# Create a new chain which we will program to mean "route through redsocks".
sudo iptables -t nat -N REDSOCKS

# Tell the new chain to ignore traffic to local, NAT, and reserved addresses.
sudo iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 100.64.0.0/10 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 198.18.0.0/15 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN

# Tell the new chain to send all other traffic to the redsocks local port.
sudo iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345

# Apply the REDSOCKS chain to all outgoing UDP traffic.
sudo iptables -t nat -A OUTPUT -p udp -j REDSOCKS

# Apply the REDSOCKS chain to all outgoing TCP traffic.
sudo iptables -t nat -A OUTPUT -p tcp -j REDSOCKS

# Tunnel the Socks5 port, port 8123, over SSH.
echo
echo 'Tethering will activate once you enter the SSH password.'
echo 'After that, press control-C to end tethering.'
echo 'Creating tunnel (Android SSH server password required).'
ssh localhost -p 2222 -D 8123 -N

# Restore the original packet filter rules.
echo
echo 'Reverting network changes.'
sudo iptables-restore "$IPTABLES_SAVE"
rm "$IPTABLES_SAVE"

# Delete the dummy network interface.
sudo ip link delete redsocks

echo 'Finished.'

将此脚本标记为可执行。您现在可以共享互联网连接了。

用法

每当您想要与 Linux 机器共享 Android 的互联网连接时,请通过 USB 电缆将其连接到 Linux 机器,启动其 SSH 服务器,在 Linux 机器上运行 Bash 脚本,在提示时输入管理员密码,并在提示时输入 SSH 服务器的密码。(如果您使用的是 SimpleSSHD,请注意它会为每个连接生成一个新密码,因此您必须从 Android 设备上读取该密码。)如果一切顺利,您将可以访问互联网,脚本将等待您结束连接。(如果您发现无法使用 DNS 解析主机,则可能需要等待一两分钟才能让系统赶上新设置。)

联网时要做个好公民。移动提供商试图阻止或限制网络共享的原因之一是用户会沉迷于他们移动的数据量,从而不公平地影响他人。由于提供商监控网络共享的常用机制可能无法检测到此设置,因此您必须自我约束并遵守合同。一个好的做法是密切关注充当 SSH 服务器的应用程序的数据使用情况,以确保它不超过移动提供商设置的网络共享限制。

当您准备断开连接时,请按 Control-c 中断 SSH 连接。然后,脚本将运行其清理命令以撤消对网络配置的所有更改(如果您连接的时间足够长,则可能再次需要您的管理员密码)并报告已完成。

相关内容