跟 UMU 一起玩 OpenWRT(入门篇15):ip-tiny 和 ip-full 的区别

起源

今天看到有网文《iptables+tproxy实现ss-redir的UDP转发的方法》说:“OpenWrt 做 UDP 转发需要的依赖是:iptables-mod-tproxy, kmod-ipt-tproxy 和 ip-full”。使用 opkg install ip 安装的默认是 ip-tiny,一般情况下都是够用的,不禁想弄明白两者有何区别。

探索

ip 命令对比测试:

  • ip-tiny
1
2
3
OBJECT := { link | address | route | rule | neigh | tunnel | maddress |
mroute | mrule | monitor | netns | macsec | token | ila |
vrf | sr }
  • ip-full
1
2
3
4
OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
vrf | sr }

即 ip-full 多了这些对象: addrlabel | ntable | tuntap | xfrm | l2tp | fou | tcp_metrics | netconf。举个例子,只安装 ip-tiny 时,运行 ip xfrm 报错如下:

Object “xfrm” is unknown, try “ip help”.

相关知识:

xfrm is an IP framework for transforming packets (such as encrypting
their payloads). This framework is used to implement the IPsec
protocol suite (with the state object operating on the Security
Association Database, and the policy object operating on the Security
Policy Database). It is also used for the IP Payload Compression
Protocol and features of Mobile IPv6.

结论

实际上,转发普通 UDP 包,并不需要 ip-full,ip-tiny 即可。

Lenovo Y1S 千兆 LAN 改 WAN

需求

Lenovo Y1S 的原 WAN 口是百兆的,连接千兆网络时,WAN 口成为瓶颈,需把两个千兆 LAN 其中一个改为 WAN。

实现

UMU 一开始直接在官方 ROM 上去改 switch,却发现行不通,因为原 WAN 口被废掉后,如果不插着网线,官方 ROM 会很智能地以为路由器是没上网的,子网内终端浏览网页时,会一直被重定向到路由器设置页面。

尝试修改 /etc/config/system 还是没解决,所以……直接刷 OpenWRT 吧……三步走:

  1. 参考《newifi mini 刷 OpenWRT》。

  2. 下载 ROM。开发版地址如下,稳定版请根据当前情况自寻链接。

    https://downloads.openwrt.org/snapshots/trunk/ramips/mt7620/openwrt-ramips-mt7620-y1s-squashfs-sysupgrade.bin

  3. 刷完再改 switch,搞定。

newifi mini 刷 OpenWRT

newifi mini,即 lenovo Y1,属于不开放 SSH 的类型,越用越不爽,还是刷了吧。

先到 http://www.xcloud.cc/download.shtml 下载“路由助手”,然后到 OpenWRT 官网下载 ROM,推荐用 trunk 上的(目前是 dd),因为 bb 和 cc 都没有集成 kmod-mt76(当然你自己手动安装是可以的,opkg install kmod-mt76),下载链接:http://downloads.openwrt.org/snapshots/trunk/ramips/mt7620/openwrt-ramips-mt7620-y1-squashfs-sysupgrade.bin。目前刷完是 OpenWrt Designated Driver r47548,5G WiFi 没问题。

由于是 trunk 版,luci 可能要自己安装,请参考文章《跟 UMU 一起玩 OpenWRT(入门篇7):安装 LUCI》。

存在几个问题:

  1. 刷完,三个网口顺序和原版是颠倒的。

  2. 5G WiFi 设置参数后似乎没有办法立刻生效,UMU 都是 reboot 一下解决。

跟 UMU 一起玩 OpenWRT(入门篇10):穿透内网

UMU 把路由器放在公司,然后在家里想登陆它,这时候就有一个问题:如何穿越到公司内网呢?本文给出的一种解决方案:SSH 反向连接。涉及的软件是 autossh。

您需要准备一台有固定外网 IP 的服务器,UMU 使用的是某某云主机(避免广告嫌疑就不说了,呵,广告位招租),如果不想出钱购买,可以用家庭 ADSL + 动态域名代替,效果可能差一些,但基本可用。

为了更清晰地说明,列一下各个角色:

  1. 控制端:UMU 的笔记本,不管在什么网络,都要求能够连接到放在公司的路由器;

  2. 中转服务器:一台某某云主机,固定 IP,用 cloud_ip 表示;

  3. 被控端:放在公司的路由器,内网 IP,用 internal_ip 表示。

基本原理:让被控端主动连接中转服务器,然后控制端连接中转服务器,就可以间接连接被控端了。

被控端安装、设置,主要参考:http://wiki.openwrt.org/doc/howto/autossh

1
2
3
4
opkg update
opkg install autossh
dropbearkey -t rsa -f /etc/dropbear/id_rsa
dropbearkey -y -f /etc/dropbear/id_rsa | grep ssh-rsa

把上面最后一行命令的输出复制下,注意只有一行,待会儿要上传到中转服务器。或者也可以把最后一条命令改为打印到文件,再用 WinSCP 下载到本地。

1
dropbearkey -y -f /etc/dropbear/id_rsa | grep ssh-rsa > /tmp/pubkey

查看一下 autossh 配置:

1
uci get autossh.@autossh[0].ssh

如果没有问题,就把中转服务器的信息设置上去:

1
2
uci set autossh.@autossh[0].ssh='-i /etc/dropbear/id_rsa -f -N -T -R 2222:localhost:22 <user>@<cloud_ip>'
uci commit

接下来登录到中转服务器(Linux Server,如果是 OpenWRT,要把以下的 ~/.ssh/authorized_keys 换成 /etc/dropbear/authorized_keys),把公钥(/tmp/pubkey)上传:

1
2
3
4
5
6
7
8
echo "key 内容" >> ~/.ssh/authorized_keys
# 或者
#cat pubkey >> ~/.ssh/authorized_keys
chmod 0700 ~/.ssh/
chmod 0600 ~/.ssh/authorized_keys
vi /etc/ssh/sshd_config
# 改为允许证书登录
service sshd restart

/etc/ssh/sshd_config 需要打开的有:

1
2
3
4
5
6
7
RSAAuthentication yes

PubkeyAuthentication yes

AuthorizedKeysFile .ssh/authorized_keys

GatewayPorts yes

到路由器上测试:

1
ssh -i /etc/dropbear/id_rsa -f -N -T -R 2222:localhost:22 <user>@<cloud_ip>

如果成功则大功告成,以后只需要 ssh 到中转服务器的 2222 端口就等于连接到路由器了。最后配合本地端口转发,可以连接很多内网机器了。如下图:

Putty

再加一台路由器,用于做本地端口转发,就可以让 Surface、iPad 之类的设备也能快乐地穿透到内网了。

跟 UMU 一起玩 OpenWRT(入门篇7):安装 LUCI

UMU 不推荐安装 LUCI,还是多打命令好,可以学习更多东西,而且 LUCI 比较浪费存储空间!

1
2
opkg update
opkg install luci-ssl

推荐使用 SSL 版本,比较安全,但比较大,如果装不下可以试试不带 SSL 的:

1
opkg install luci

您可能不习惯默认的主题(luci-theme-bootstrap),Flash 够大的话,还是装个常用的:

1
opkg install luci-theme-openwrt

开启服务:

1
/etc/init.d/uhttpd start

设置开机自动运行(不推荐):

1
/etc/init.d/uhttpd enable

跟 UMU 一起玩 OpenWRT(入门篇1):硬件选型和刷机

看了《跟hoowa学做智能路由》系列,http://www.leiphone.com/diy-a-smart-router.html,也想写点自己的经验,大家可以先看 hoowa 童鞋的,写得很好。UMU 用的硬件和他不同而已。

首先声明,UMU 不是 D-Link 员工,也不卖 DIR-505,用它完全是当下对比几个可选项筛选后的结果。理由:

  1. 本身就是不死 Bootloader,刷坏了固件用网线就可以救,把电脑 IP 设为 192.168.0.100,按住 Reset 开机,Web 浏览器访问 192.168.0.1。前面写的《不拆机给 D-Link DIR-505 刷上不死 U-Boot》完全是蛋疼地研究过程,对一般用户 UMU 建议不要刷,因为没有 JTAG,刷固件本来就不死,不小心刷坏 Bootloader,就只能拆机上编程器了,这明显作死。

  2. 配置比较高(相比 TP-Link 坑爹级同价位产品),8MB Flash,64MB RAM,UMU 手头上还有三个 TP 的(TL-WR841N、743N、941N)都只有它一半。有 USB 2.0 接口,743N 的 USB 是 1.1 的。

  3. 国内电商有得买,而且价格便宜,UMU 买的时候是 78 块。

  4. 小巧,方便携带,随时开撸!

也说一下它的缺点:没有外接天线,所以您懂的,信号必然比较弱,不适合“穿墙”族……然后 RJ45 口只有一个,有时候会不太方便。它最适合的使用场景是研究 OpenWRT、短距离和出差便捷使用。

请自行根据当下情况选择,毕竟新的硬件总是越来越强大,还越来越便宜。

接下来就刷个 OpenWRT 先~目前没有稳定发行版支持 DIR-505,所以要在 trunk 下找,下载目录是:http://downloads.openwrt.org/snapshots/trunk/ar71xx/。如果直接开刷,很可能失败,因为 D-Link 是有锁区的,OpenWRT.org 编译的 ROM 不是为中国版准备的,所以要动一下手脚先。上 WinHex 改 ROM,下面两张图分别是中国版和国际版:

中国版

国际版

两者只是图片指出的位置不同而已,可以自己改,如果把 OpenWRT 的 ROM 改为 CN 也无法在原厂 ROM 下刷成功的话,可以先找个官方的 DEF ROM 改为 CN,刷一下,再刷 OpenWRT 原版的 DEF ROM。

跟 UMU 一起玩 OpenWRT(高级篇2):不拆机刷不死 U-Boot

在上一篇《跟 UMU 一起玩 OpenWRT(高级篇1):编译不死 U-Boot》介绍了如何编译不死 U-Boot,但是不死 U-Boot 的作者只介绍了用 TTL 线刷方法,UMU 可不想拆机,毕竟拆机感觉并不好……

第一个思路是刷上 DD-WRT 固件,但是找了一下 DD-WRT 木有支持 DIR-505,只好继续蛋疼地编译 OpenWRT。

第一遍在虚拟机从 12:20 编译到 23:56,花费将近 12 小时……刚开始时,有一个下载过程,不断失败,想想是因为公司的网络太烂,于是把下载脚本改了一下:

<openwrt-svn-dir>/trunk/scripts/download.pl 中的 wget -t5 --timeout=20 --no-check-certificate 改为 wget -t5 --timeout=120 --no-check-certificate

第二天来,刷上,没问题,于是开始改代码去掉 U-Boot 写保护,参考这篇《Openwrt 中刷写 uboot ARThttp://see.sl088.com/wiki/Openwrt_%E4%B8%AD%E5%88%B7%E5%86%99_uboot_art,但结果很不幸,型号不同嘛!

接下来,凭自己的编程水平了,尝试改 <openwrt-svn-dir>/trunk/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-505-a1.c,加入下面两个结构体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
static struct mtd_partition dir505_partitions[] = {
{
.name = "u-boot",
.offset = 0,
.size = 0x010000,
.mask_flags = 0,
}, {
.name = "art",
.offset = 0x010000,
.size = 0x010000,
}, {
.name = "mac",
.offset = 0x020000,
.size = 0x010000,
}, {
.name = "nvram",
.offset = 0x030000,
.size = 0x010000,
}, {
.name = "language",
.offset = 0x040000,
.size = 0x040000,
}, {
.name = "firmware",
.offset = 0x080000,
.size = 0x780000,
.mask_flags = 0,
}
};

static struct flash_platform_data dir505_flash_data = {
.parts = dir505_partitions,
.nr_parts = ARRAY_SIZE(dir505_partitions),
};

并将 dir_505_a1_setup 函数里的 ath79_register_m25p80(NULL); 改为 ath79_register_m25p80(&dir505_flash_data);

测试还是无效……看来必须在源头上使 MTD_WRITEABLE 无效掉,grep -r MTD_WRITEABLE <openwrt-svn-dir>/trunk/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.10.36/drivers/mtd,看到几处关键的地方:

1
if (!(ubi->mtd->flags & MTD_WRITEABLE)) {

1
if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))

主要在 mtd_erase、mtd_write 等函数,很明显,C 语言不管在什么平台都是很好懂,看几眼就搞定了,原理是使 MTD_WRITEABLE 这个标志无用掉,您可以设置,但是我把判断这个标志的代码全干掉了,设了也是白设!

最后编译好的 openwrt-ar71xx-generic-dir-505-a1-squashfs-sysupgrade.bin,用 sysupgrade 刷一下,reboot 后再用 mtd 刷不死 U-Boot,一切顺利,成功刷上不死 U-Boot!

跟 UMU 一起玩 OpenWRT(高级篇1):编译不死 U-Boot

UMU 2010 年初就玩 OpenWRT/DD-WRT 了,蛋似编译东西还是初学者,本文纯属蛋疼的过程,欢迎批评教育,谢谢……

首先到 https://github.com/pepe2k/u-boot_mod 看明白作者的说明。这里简单说一下原理:固件(firmware)刷坏,但 U-Boot 没坏,这是半砖,可以用 TTL 线连路由器,通过 U-Boot 的功能刷好 firmware。如果两者都坏了,叫全砖,只能把 Flash 拆下来,用编程器刷好 U-Boot 和 firmware。不死 U-Boot 就是修改了 U-Boot 的实现,使我们可以用 RJ-45 网线来救砖,省去拆机搭 TTL 线的麻烦。

本质上说,这东西并非真的不死,只要 U-Boot 被刷坏,还是会死,不过几率不大,因为 OpenWRT 官方发行的 ROM 全都是保护 U-Boot 区域的,根据 UMU 的经验,只有三个情况会不小心或故意刷坏:

  1. 从原厂固件刷不良固件;
  2. 在 DD-WRT 下搞破坏(DD-WRT 没有保护 U-Boot);
  3. 自制固件去掉 U-Boot 写保护后搞破坏……

如果您真的这么蛋疼,还是准备编程器吧,只要是软件问题,在编程器面前没有砖的概念。(JTAG 也是救砖神器,但不是每台路由器都有,比如 DIR-505 就没有!)

由于 UMU 是 Windows 程序员,平时没有安装 Linux 桌面的习惯,蛋似由于做快游项目,买了不少服务器,都是 CentOS,所以第一步就是在 CentOS 上尝试编译,后来,您们懂的,爆出各种 213 码!服务器系统还是不适合开发!

不得已就在 Hyper-V Server 2012 上安装了 Ubuntu 12.04.1-desktop-i386,本来是想安装 x64 版本的,但又怕这些嵌入式的东西对 x64 可能支持不够好,算了,不要装 13 了。

接下来是选择编译环境了,按照 UMU 对 OpenWRT 的好感,明显是选择 OpenWrt Toolchain for AR71xx MIPS,然后开始编译,哗哗哗,编译好了……最后编译出来的 bin 却是 64KB+110B,尼玛,这 size 超标了,刷进去不是不死,是立刻死!

试验 Sourcery CodeBench Lite Edition for MIPS GNU/Linux 可行。推测作者其实并没有用 OpenWrt Toolchain 编译过,而是用 Sourcery CodeBench,所以……为了节省时间,还是用后者吧!吐槽一下,这是商业软件,虽然有免费的 Lite 版本……

make dlink_dir505 一下,顺利编译出来,UMU 还小修改了一下 Web 界面,加入了自己的特色,不过要提醒一下,不要加太多,会爆……只有 64KB 的空间!