用 LEDE 实现短信验证码转发

前段时间貌似是因为电信网络维护停止了 CDMA 的本网漫游,需要漫游到 WCDMA。奈何短信机是台红米 1S,不支持 WCDMA,导致收不到各种验证码。于是打算使用 3G 模块接收短信,并转发到 Telegram。

经过一番调查后发现:

  1. 日本早在 2012 年 5 月 31 日全面停止了 2G 网络的服务,于是 GSM 不可行。
  2. 打电话给电信回复说:CDMA 维护,恢复时间不定,请使用 WCDMA 网络。这说明异网漫游是正常的。
  3. DoCoMo 的 WCDMA 频段是 Band 1,6,9,19。

然后去日拍翻了下,刚好有一款符合要求:


用 LEDE 实现短信验证码转发_第1张图片
image.png
用 LEDE 实现短信验证码转发_第2张图片
华为 E173U

标准 AT 指令操作,支持收发短信。

测试入网

正常入网

正常入网,接着测试 AT 指令

测试 AT 指令

一切正常。

配置 LEDE

首先需要安装 USB 驱动

opkg install kmod-usb-serial kmod-usb-serial-wwan kmod-usb-serial-option usb-modeswitch

主要就是这些,可能还有其他需要安装的我没有列出来,具体请参考 Use 3g/UMTS USB Dongle for WAN connection

之后就是配置短信服务,这里用到的是 smstools3,所以

opkg install smstools3

接着需要配置 smstool3,配置文件在 /etc/smsd.conf,修改完之后应该是这样:

#
# Description: Main configuration file for the smsd
#

devices = GSM1
incoming = /var/spool/sms/incoming
outgoing = /var/spool/sms/outgoing
checked = /var/spool/sms/checked
failed = /var/spool/sms/failed
sent = /var/spool/sms/sent
receive_before_send = no
autosplit = 3
incoming_utf8 = yes

# 轮询短信间隔时间
delaytime = 1

[GSM1]
# 将短信保存在上网卡中(更快,不支持的话请使用 SM 模式)
init = AT+CPMS="ME","ME","ME"

# 将短信保存在 USIM 卡中
# init = AT+CPMS="SM","SM","SM"

device = /dev/ttyUSB0
incoming = yes

# 如果 USIM 卡有设置 pin 码需要设置这行来解锁
# pin = 0000

# 波特率,一般都是 115200,不对的话请自行修改
baudrate = 115200

# 如果检测得到信息但是无法读取需要修改这里的读取模式
check_memory_method = 2

report_device_details = yes
signal_quality_ber_ignore = yes
check_network = no

如果你的上网卡的串口路径不是 /dev/ttyUSB0 请查找后自行修改:

ls /dev | grep tty
...
ttyUSB0
ttyUSB1
ttyUSB2
...

启动服务

/etc/init.d/smstools3 restart

这样一来就能正常收到短信了。
顺便一提,E173U 的指示灯:

  • 闪绿灯:初始化正常,正在搜索网络
  • 闪蓝灯:正常入网

不出意外的话,在配置好上网卡的软件包后插上上网卡就能看到蓝灯闪烁,代表正常入网。

测试 smstools

刚刚配置好了 smstools 但是不知道是否工作正常,于是查看日志:

2017-06-08 03:25:34,7, smsd: Done: startup_check (shell), execution time 0 sec., status: 0 (0)
2017-06-08 03:25:34,4, smsd: File mode creation mask: 022 (0644, rw-r--r--).
2017-06-08 03:25:34,5, smsd: Outgoing file checker has started. PID: 9684.
2017-06-08 03:25:34,7, smsd: All PID's: 9684,9686
2017-06-08 03:25:34,5, GSM1: Modem handler 0 has started. PID: 9686.
2017-06-08 03:25:34,5, GSM1: Using check_memory_method 1: CPMS is used.
2017-06-08 03:25:34,6, GSM1: Checking device for incoming SMS
2017-06-08 03:25:34,6, GSM1: Checking if modem is ready
2017-06-08 03:25:34,7, GSM1: -> AT
2017-06-08 03:25:34,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:35,7, GSM1: <- OK
2017-06-08 03:25:35,6, GSM1: Pre-initializing modem
2017-06-08 03:25:35,7, GSM1: -> ATE0+CMEE=1;+CREG=2
2017-06-08 03:25:35,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:35,7, GSM1: <- OK
2017-06-08 03:25:35,6, GSM1: Checking if modem needs PIN
2017-06-08 03:25:35,7, GSM1: -> AT+CPIN?
2017-06-08 03:25:35,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:36,7, GSM1: <- +CPIN: READY OK
2017-06-08 03:25:36,6, GSM1: Initializing modem
2017-06-08 03:25:36,7, GSM1: -> AT^CURC=0
2017-06-08 03:25:36,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:36,7, GSM1: <- OK
2017-06-08 03:25:36,7, GSM1: -> AT+CSQ
2017-06-08 03:25:36,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:37,7, GSM1: <- +CSQ: 12,99 OK
2017-06-08 03:25:37,6, GSM1: Signal Strength Indicator: (12,99) -89 dBm (Workable)
2017-06-08 03:25:37,6, GSM1: Checking if Modem is registered to the network
2017-06-08 03:25:37,7, GSM1: -> AT+CREG?
2017-06-08 03:25:37,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:37,7, GSM1: <- +CREG: 2,5, 66, C018 OK
2017-06-08 03:25:37,6, GSM1: Modem is registered to a roaming partner network
2017-06-08 03:25:37,6, GSM1: Location area code: 66, Cell ID: C018
2017-06-08 03:25:37,7, GSM1: -> AT+CSQ
2017-06-08 03:25:37,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:38,7, GSM1: <- +CSQ: 13,99 OK
2017-06-08 03:25:38,6, GSM1: Signal Strength Indicator: (13,99) -87 dBm (Workable)
2017-06-08 03:25:38,6, GSM1: Selecting PDU mode
2017-06-08 03:25:38,7, GSM1: -> AT+CMGF=0
2017-06-08 03:25:38,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:38,7, GSM1: <- OK
2017-06-08 03:25:38,7, GSM1: -> AT+CIMI
2017-06-08 03:25:38,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:39,7, GSM1: <- 204046003816003 OK
2017-06-08 03:25:39,7, GSM1: -> AT+CGSN
2017-06-08 03:25:39,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:39,7, GSM1: <- 352216049835909 OK
2017-06-08 03:25:39,5, GSM1: CGSN: 352216049835909
2017-06-08 03:25:39,5, GSM1: IMSI: 204046003816003
2017-06-08 03:25:39,6, GSM1: Checking if reading of messages is supported
2017-06-08 03:25:39,7, GSM1: -> AT+CPMS?
2017-06-08 03:25:39,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:25:40,7, GSM1: <- +CPMS: "SM",1,40,"SM",1,40,"SM",1,40 OK
2017-06-08 03:25:40,7, GSM1: ## Start of device details
2017-06-08 03:25:40,7, GSM1: # Manufacturer identification:
2017-06-08 03:25:40,7, GSM1: -> AT+CGMI
2017-06-08 03:25:40,7, GSM1: <- huawei
OK
2017-06-08 03:25:40,7, GSM1: # Model identification:
2017-06-08 03:25:40,7, GSM1: -> AT+CGMM
2017-06-08 03:25:41,7, GSM1: <- E173
OK
2017-06-08 03:25:41,7, GSM1: # Revision identification:
2017-06-08 03:25:41,7, GSM1: -> AT+CGMR
2017-06-08 03:25:41,7, GSM1: <- 11.126.83.00.00
OK
2017-06-08 03:25:41,7, GSM1: # New message indications, list of supported modes:
2017-06-08 03:25:41,7, GSM1: -> AT+CNMI=?
2017-06-08 03:25:42,7, GSM1: <- +CNMI: (0,1,2),(0,1,2,3),(0,2),(0,1,2),(0,1)
OK
2017-06-08 03:25:42,7, GSM1: # New message indications, current settings:
2017-06-08 03:25:42,7, GSM1: -> AT+CNMI?
2017-06-08 03:25:42,7, GSM1: <- +CNMI: 0,0,0,0,0
OK
2017-06-08 03:25:42,7, GSM1: # Preferred message storage, list of supported mem's:
2017-06-08 03:25:42,7, GSM1: -> AT+CPMS=?
2017-06-08 03:25:43,7, GSM1: <- +CPMS: ("ME","MT","SM","SR"),("ME","MT","SM","SR"),("ME","MT","SM","SR")
OK
2017-06-08 03:25:43,7, GSM1: # Phonebook storage, available mem's:
2017-06-08 03:25:43,7, GSM1: -> AT+CPBS=?
2017-06-08 03:25:43,7, GSM1: <- +CPBS: ("SM","EN","ON")
OK
2017-06-08 03:25:43,7, GSM1: # List messages, list of supported stat's:
2017-06-08 03:25:43,7, GSM1: -> AT+CMGL=?
2017-06-08 03:25:44,7, GSM1: <- +CMGL: (0-4)

没毛病。

发个短信试试

2017-06-08 03:28:34,6, GSM1: Checking memory size
2017-06-08 03:28:34,7, GSM1: -> AT+CPMS?
2017-06-08 03:28:34,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:28:34,7, GSM1: <- +CPMS: "SM",2,40,"SM",2,40,"SM",2,40 OK
2017-06-08 03:28:34,6, GSM1: Used memory is 2 of 40
2017-06-08 03:28:34,6, GSM1: Trying to get stored message 1
2017-06-08 03:28:34,7, GSM1: -> AT+CMGR=1
2017-06-08 03:28:34,7, GSM1: Command is sent, waiting for the answer
2017-06-08 03:28:35,7, GSM1: <- +CMGR: 0,,146 07911356044902000405A15955F5000871608020820023829A8C8BC17801003300370034003000340039FF0C60A86B63572875284E007F51901A767B5F55FF0C5982975E672C4EBA64CD4F5CFF0C8BF780547CFB0039003500350035003530028BF752FF57284EFB4F5577ED4FE1621690AE4EF694FE63A57684987597624E2D8F9351659A8C8BC17801FF010020005B62DB554694F6884C005D OK
2017-06-08 03:28:35,5, GSM1: SMS received, From: 95555
2017-06-08 03:28:35,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.IgkBhN
2017-06-08 03:28:35,7, GSM1: Running eventhandler: /root/sms RECEIVED /var/spool/sms/incoming/GSM1.IgkBhN
2017-06-08 03:28:36,7, GSM1: Done: eventhandler, execution time 1 sec., status: 0 (0)

没毛病。

查看 incoming 文件夹中的文件 /var/spool/sms/incoming/GSM1.IgkBhN

From: 95555
From_TOA: A1 national, ISDN/telephone
From_SMSC: 316540942000
Sent: 17-06-08 02:28:00
Received: 17-06-08 03:28:35
Subject: GSM1
Modem: GSM1
IMSI: 204046003816003
Report: no
Alphabet: UCS2
Length: 65

▒▒▒▒xxxxxxx▒
`▒kcW(u(Q▒v{_U▒
Y▒▒^g,N▒d▒O\▒
▒▒T|▒955550▒▒R▒W(N▒OUw▒O▒b▒▒N▒▒c▒v▒▒u▒bN-▒▒Qe▒▒▒▒x▒ [b▒UF▒▒L]

这里的正文显示为乱码。上面也有提到 Alphabet: UCS2,于是使用 iconv 转换。

opkg install iconv

这里需要注意的是,需要去掉前面的 ASCII 部分,不然会变成乱码。

sed -i '1,12d' /var/spool/sms/incoming/GSM1.IgkBhN
iconv -f UTF-16BE -t UTF-8 < /var/spool/sms/incoming/GSM1.IgkBhN
验证码xxxxxx,您正在用一网通登录,如非本人操作,请联系95555。请勿在任何短信或邮件链接的页面中输入验证码! [招商银行]

于是我们就得到了完整的短信。

转发短信

因为日常使用 Telegram 比较多,自然就想到了 Telegram Bot。

找 BotFather 要一个 Bot

用 LEDE 实现短信验证码转发_第3张图片
BotFather

找 @get_id_bot 这个 Bot 拿到自己的 chat id

用 LEDE 实现短信验证码转发_第4张图片
@get_id_bot

然后我们需要一个 hook,在收到短信的时候执行 shell,所幸 smstools3 有这样的 hook 给我们直接用。

编辑 /etc/smsd.conf
[GSM1] 的末尾加上:

eventhandler = /root/sms

这样在收到短信时就会调用这个 shell 并传递两个参数:

  1. 事件类型,比如收到短信是 RECIVED
  2. 短信存档路径

于是我们的 /root/sms 如下:

#!/bin/sh

TMPFILE1=$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)
TMPFILE2=$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 8)

cat $2 > $TMPFILE2

awk 'NR==1 || NR==4 || NR==5' $TMPFILE2 >> $TMPFILE1
sed -i '1,12d' $TMPFILE2
iconv -f UTF-16BE -t UTF-8 < $TMPFILE2 >> $TMPFILE1


CONTENT=`cat $TMPFILE1`

echo SMSD alarm: $1 $2 >> /root/sms.txt
curl -i -X POST \
  -F "chat_id=" \
  -F "text=${CONTENT}" \
  "https://api.telegram.org/bot/sendMessage"

rm $TMPFILE1 $TMPFILE2

记得加上执行权限

chmod +x /root/sms

其中 chat_id 为你自己的 chat id,并替换网址中的 apikey。
最后记得在 Telegram 中找到你的 Bot 发送 /start 不然 Bot 没有权限给你发送消息。

升级 curl

测试脚本后发现并不能正常运行,原因是 LEDE 17.01.1 的 curl 有一些 bug 尚未修复。

于是我们需要升级 curl 和 libcurl 到 snapshot 的版本。

https://downloads.lede-project.org/snapshots/packages/
在这里找到路由器对应的指令集,进入 base 文件夹下载 curl 和 libcurl 两个软件包。

比如 ar71xx 的是这两个:
curl
libcurl

使用 opkg 安装:

wget https://downloads.lede-project.org/snapshots/packages/mips_24kc/base/curl_7.54.0-1_mips_24kc.ipk
wget https://downloads.lede-project.org/snapshots/packages/mips_24kc/base/libcurl_7.54.0-1_mips_24kc.ipk
opkg remove curl
opkg remove libcurl
opkg install libcurl_7.54.0-1_mips_24kc.ipk
opkg install curl_7.54.0-1_mips_24kc.ipk

这样 curl 就能正常工作了。

测试 Bot

重启 smstools3

/etc/init.d/smstools3 restart

发送短信并查看日志

2017-06-08 04:35:01,6, GSM1: Checking memory size
2017-06-08 04:35:02,7, GSM1: -> AT+CPMS?
2017-06-08 04:35:02,7, GSM1: Command is sent, waiting for the answer
2017-06-08 04:35:02,7, GSM1: <- +CPMS: "SM",2,40,"SM",2,40,"SM",2,40 OK
2017-06-08 04:35:02,6, GSM1: Used memory is 2 of 40
2017-06-08 04:35:02,6, GSM1: Trying to get stored message 1
2017-06-08 04:35:02,7, GSM1: -> AT+CMGR=1
2017-06-08 04:35:02,7, GSM1: Command is sent, waiting for the answer
2017-06-08 04:35:02,7, GSM1: <- +CMGR: 0,,146 07911356044902000405A15955F5000871608030434423829A8C8BC17801003200300035003600380037FF0C60A86B63572875284E007F51901A767B5F55FF0C5982975E672C4EBA64CD4F5CFF0C8BF780547CFB0039003500350035003530028BF752FF57284EFB4F5577ED4FE1621690AE4EF694FE63A57684987597624E2D8F9351659A8C8BC17801FF010020005B62DB554694F6884C005D OK
2017-06-08 04:35:02,5, GSM1: SMS received, From: 95555
2017-06-08 04:35:02,6, GSM1: Wrote an incoming message file: /var/spool/sms/incoming/GSM1.NHChff
2017-06-08 04:35:02,7, GSM1: Running eventhandler: /root/sms RECEIVED /var/spool/sms/incoming/GSM1.NHChff
2017-06-08 04:35:04,7, GSM1: Done: eventhandler, execution time 2 sec., status: 0 (0)
2017-06-08 04:35:04,3, GSM1: Exec: eventhandler said something:
2017-06-08 04:35:04,3, GSM1: ! HTTP/1.1 100 Continue
2017-06-08 04:35:04,3, GSM1: !
2017-06-08 04:35:04,3, GSM1: ! HTTP/1.1 200 OK
2017-06-08 04:35:04,3, GSM1: ! Server: nginx/1.10.0
2017-06-08 04:35:04,3, GSM1: ! Date: Wed, 07 Jun 2017 19:35:04 GMT
2017-06-08 04:35:04,3, GSM1: ! Content-Type: application/json
2017-06-08 04:35:04,3, GSM1: ! Content-Length: 637
2017-06-08 04:35:04,3, GSM1: ! Connection: keep-alive
2017-06-08 04:35:04,3, GSM1: ! Access-Control-Allow-Origin: *
2017-06-08 04:35:04,3, GSM1: ! Access-Control-Allow-Methods: GET, POST, OPTIONS
2017-06-08 04:35:04,3, GSM1: ! Access-Control-Expose-Headers: Content-Length,Content-Type,Date,Server,Connection
2017-06-08 04:35:04,3, GSM1: ! Strict-Transport-Security: max-age=31536000; includeSubdomains
2017-06-08 04:35:04,3, GSM1: !
2017-06-08 04:35:04,3, GSM1: ! {"ok":true,"result":{"message_id":15,"from":{"id":362363438,"first_name":"SMS Forward Bot","username":"sms_forward_bot"},"chat":{"id":70962251,"first_name":"Jesse","last_name":"Zhu","username":"ITJesse","type":"private"},"date":1496864104,"text":"From: 95555\nSent: 17-06-08 03:34:44\nReceived: 17-06-08 04:35:02\n\u9a8c\u8bc1\u7801205687\uff0c\u60a8\u6b63\u5728\u7528\u4e00\u7f51\u901a\u767b\u5f55\uff0c\u5982\u975e\u672c\u4eba\u64cd\u4f5c\uff0c\u8bf7\u8054\u7cfb95555\u3002\u8bf7\u52ff\u5728\u4efb\u4f55\u77ed\u4fe1\u6216\u90ae\u4ef6\u94fe\u63a5\u7684\u9875\u9762\u4e2d\u8f93\u5165\u9a8c\u8bc1\u7801\uff01 [\u62db\u5546\u94f6\u884c]"}}
2017-06-08 04:35:04,3, GSM1: Exec: eventhandler encountered errors:
2017-06-08 04:35:04,3, GSM1: !   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
2017-06-08 04:35:04,3, GSM1: !                                  Dload  Upload   Total   Spent    Left  Speed
100  1111  100   637  100   474    337    251  0:00:01  0:00:01 --:--:--   366
2017-06-08 04:35:04,6, GSM1: Deleting message 1
2017-06-08 04:35:05,7, GSM1: -> AT+CMGD=1
2017-06-08 04:35:05,7, GSM1: Command is sent, waiting for the answer
2017-06-08 04:35:05,7, GSM1: <- OK

并且 Telegram 收到推送

用 LEDE 实现短信验证码转发_第5张图片
Telegram 收到推送

结语

最后用 1200 日元解决了这个世纪难题,不用背两手机在包里,直接插路由器上也不用单独供电。
虽然还能实现用 bot 发送短信,但是没有这个需求就不继续做了。
然后立马登陆网银还了信用卡 :)

你可能感兴趣的:(用 LEDE 实现短信验证码转发)