一日,某不安好心者在酷安的 Xposed 模块 “App Setting” 的评论区发布了一条评论——“APP Setting 专业版”。一位用户下载使用后中招——微信密码泄露,账户被盗刷。
跨内外网远程操作Spark
问题
我们知道通过反向ssh可以借助有固定IP的外网服务器登陆没有外网IP的内网主机,但是我们在真正使用的时候可能不仅仅需要远程登陆,可能还会需要内网机器中其他端口提供的服务。比如现在我需要在远处利用Spark程序去操作内网机器里的分布式系统进行工作,这就至少需要调用内网机器的7077端口(默认的Spark调用端口)和9000端口(默认的hdfs端口)。那么这时候我们应当怎么处理呢?
解决思路
最容易想到的解决方案就是同样利用反向ssh,将内网的9000端口映射到服务器的9000端口上。这一点显然是很容易做到的,与利用反向ssh进行登陆的操作是类似的。但是当我想当然的去telnet服务器的9000端口时却发现报了下面的错误:
1 | myths@business:~$ telnet mythsman.com 9000 |
他提示我对这个端口的访问被拒绝了,于是我登陆服务器,去查看端口情况:
1 | root@server:~# ss -ant|grep 9000 |
仔细一看才发现,原来利用反向ssh进行端口绑定的时候,端口的访问权限默认只给了本机(127.0.0.1),从其他IP访问这个端口的请求都会被拒绝。要是这个权限不受限制,对所有IP(0.0.0.0)都能访问就好了。
但是想了想好像也不知道怎么能够修改这个值,于是我就采取了一个折中的办法,干脆把这个端口再进行一次转发,用另一对外的端口转发出去。
这里我采用的是rinetd工具(internet “redirection server”),用在apt商店里可以直接下载。用这个工具进行端口转发十分的方便。
rinetd工具
这个工具的用法很简单,只有一个配置文件/etc/rinetd.conf:
1 | # |
利用这个配置文件,我们首先可以利用allow 和deny语句,修改允许访问的IP和拒绝访问的IP;然后我们可以用下面的格式来修改转发表:
1 | # bindadress bindport connectaddress connectport |
首先是期望发送的IP以及端口,接着是提供服务的IP和端口,每一行就是一个条目,十分清楚。
这里我把只允许127.0.0.1访问的50070端口发送到面向所有IP的50071端口。修改过后,我们就可以重启rinetd服务来使其生效。
这样就可以在利用其外网IP:新端口来访问原来无法访问的端口了。
配置总结
上面是我们的总体思路,下面就开始针对Spark来详细配置一下。
准备号进行Spark远程开发需要的Spark的7077端口、Hdfs的9000端口、hadoop的Web显示50070端口、ssh登陆的22端口。
在内网主机上配置反向SSH:
1
2
3
4autossh -M 2100 -NfR 9000:localhost:9000 root@mythsman.com
autossh -M 2200 -NfR 7077:192.168.131.198:7077 root@mythsman.com
autossh -M 2300 -NfR 2222:localhost:22 root@mythsman.com
autossh -M 2400 -NfR 50070:localhost:50070 root@mythsman.com注意到,7077端口的本地IP用的不是localhost,而是他本身在内网里的IP。这是因为Spark服务默认设置的就是这个值,和hadoop的不一样:
1
2myths@node5:~/spark/conf$ss -ant|grep 7077
LISTEN 0 128 ::ffff:192.168.131.198:7077 :::*修改服务器上的/etc/rinetd.conf配置:
1
2
3
4# bindadress bindport connectaddress connectport
0.0.0.0 50071 127.0.0.1 50070
0.0.0.0 7078 127.0.0.1 7077
0.0.0.0 9001 127.0.0.1 9000这样我们其实就已经把网络链路配置好了,访问50071端口就能够看到hadoop的web页面了,也可以跑跑Spark的测试程序:
1
2
3
4
5
6
7
8
9
10
11import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
object Test {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("Spark App").setMaster("spark://mythsman.com:7078").setJars(List("/home/myths/Desktop/scala/Test/jar/Test.jar"))
val sc = new SparkContext(conf)
val datafile = sc.textFile("hdfs://mythsman.com:9001/user/myths/dataset/data",50)
sc.stop()
}
}程序连接成功,hdfs读取成功,搞定。
其他
搞完了这个突然想起来之前用反向ssh进行内网登陆的时候还要先登陆服务器再登陆内网,甚是麻烦,我们其实完全可以再利用rinetd工具进行一次转发,这样就能直接用服务器的IP+转发后的端口直接登陆内网主机 了。
Eclipse下Spark+ScalaIDE开发环境部署
刚开始学Spark,之前一直都是在服务器里用Spark-shell进行简单学习的,后来觉得这样实在是很不方便,于是就决定利用Eclipse ide来进行开发,不过这当中遇到了很多问题,搞了半天总算搞得差不多了,下面就记录下环境搭建的步骤方便重新配置。
当前环境
在配置eclipse的开发环境前,我已经在服务器中配置好了hadoop+scala+spark的环境:
- hadoop 2.7.2
- spark 1.6.2
- scala 2.10.4
- jdk1.7
- Linux系统
由于服务器本身性能强劲,我采用Standerdalone模式,没有slave。
同时,本机也配置了同样的hadoop、spark、scala的环境(一方面是方便本机测试,另一方面是提供必要的jar包)。
下载配置Eclipse+Scala
eclipse本身不支持scala语言,但是有一款很不错的插件Scala-IDE,利用这个插件,eclipse就能很好的支持scala语言的开发了。
Scala-IDE官网在这里,这个社区现在还很活跃,一直在更新产品,不过这也导致了我们在下载配置的时候要十分注意版本选择:
- 保证Scala-ide插件与本地的Scala版本一致,这一点不用多说,但是一定不要抱着”版本落后一点也没事”的侥幸心理。
- 保证Scala-ide插件与eclipse的版本要匹配,否则就会造成一堆错误。因此我们通常不要先急着下eclipse,而是要先根据自身的scala版本选择好Scala-ide版本,再根据Scala-ide版本选择eclipse版本。
- 如果主页上找不到历史版本的Scala-ide,去这里找。
较新版本的Scala-ide可能会集成好对应的eclipse,不过如果版本较老则很可能需要自己下载eclipse。
对于eclipse而言没有过多要求,由于我们用Scala语言开发,因此不需要附带其他的东西。然后在eclipse->help->install new software中加上Scala-ide插件的地址就会弹出一些可以下载的内容。选择下面的两个组件即可:
- Scala IDE for Eclipse
- Scala IDE for Eclipse dev support
下载好后他会提示重启、更新之类的操作,照做就好。
最后我们打开eclipse->window->open perspective->other对话框,选择Scala视图,即完成了eclipse+scala ide 的基本配置。
做到这一步,基本就能够编写普通的Scala程序了,比如:
1 | object Test { |
运行Spark
说白了Spark其实也算作Scala程序,因此和普通Scala程序配置方法没有太多不同,不过一定要确保需要的jar包都有,否则就会出一堆的ClassNotFound的错。
Spark需要的jar包基本上至少要有两部分:
第一部分就是$SPARK_HOME下的lib文件夹中的包。这一部分很容易理解。
第二部分就是对应的hadoop的包,这一部分很容易被忽略,而且hadoop的包比较分散,加起来还比较麻烦。我是在配置好hadoop之后,输入hadoop classpath,来查看hadoop需要的jar包,然后把这些jar包加入项目的build path里。
配置好后理论上就可以写spark程序了。不过对于不同的开发方式,实际用的时候也有区别。如果是用本机配置的spark,那么在开启spark服务后,下面的程序就可以直接run as scala application了:
1 | import org.apache.spark.SparkConf |
在伴随着一堆log的输出中,我们就可以看到输出的结果。
但是,如果我们想直接用远程的服务器中的spark服务来运行的话,仅仅修改setMaster的值则会报”主类找不到”之类的错误,这是因为我们还得把jar包发给远程的服务器,这样他才能找到代码。我们只需要将项目导出为一个jar包,然后将代码修改如下:
1 | import org.apache.spark.SparkConf |
setMaster里的是服务器的地址,以及默认接受远程服务的7077端口,然后再在setJars里添加本地导出的jar包的地址。这样基本就能正常的运行spark程序了。
利用反向ssh从外网访问内网主机
前言
最近遇到一个问题,就是过几天我需要离开学校,而且到时候仍然想登陆校园网里的一台服务器进行工作;但是我又没有校园网网关的操作权限,不能做端口映射,也不能搞到校园网内部主机的外网ip,而且学校自己提供的vpn又根本没法用。研究了半天,总算找到了一个比较不错的利用反向ssh(reverse ssh tunnel)进行内网登陆的解决方案。
工作原理
之所以很多转发的方法无法应用在这里,就是因为内网主机对外网其实是不可见的,也就是说外部主机不能用一般的方法访问到内部主机。那么我们就想了,能不能用内网主机找外网主机,找到之后再把这条内网主机登陆外网的信道转换成外网主机登陆内网的信道呢?辛运的是,这个方法的确是可行的,这也就是所谓反向ssh最通俗的理解,这就像寄信一样,”虽然我不知道你的地址,但是你知道我的地址,那么你就先给我写封信,告诉我你的地址,然后我不就可以回信给你了么?“。
操作步骤
由于我们自己使用的电脑未必有外网ip,因此我们需要一个有固定外网ip的服务器(随便搞个腾讯云阿里云的小机子就行),然后用这台服务器与内网的机子进行通信,我们到时候要先登陆自己的服务器,然后再利用这个服务器去访问内网的主机。
1、准备好有固定ip的服务器A,以及待访问的内网机器B。两者都开着sshd服务,端口号默认都是22。顺便做好ssh免密码登陆。
2、内网主机B主动连接服务器A,执行以下命令:
1 | $ ssh -NfR 1111:localhost:22 username@servername -p 22 |
这条命令的意思是在后台执行(-f),不实际连接而是做port forwarding(-N),做反向ssh(-R),将远程服务器的1111端口映射成连接本机(B)与该服务器的反向ssh的端口。
附:这里有必要加强一下记忆,这个端口号一不小心就容易搞混。。man文档中的参数命令是这样的:
1 | -R [bind_address:]port:host:hostport |
bind_address以及其后面的port是指远程主机的ip以及端口,host以及其后的hostport是指本机的ip和端口。由于ssh命令本身需要远程主机的ip(上上条命令中的servername),因此这个bind_address原则上是可以省略的。
执行完这条命令,我们可以在服务器A上看到他的1111端口已经开始监听:
1 | $ ss -ant |grep 1111 |
3、在上面的操作中,这个1111端口就已经映射成了内网主机B的22端口了,现在我们只要ssh到自己的这个端口就行了。在服务器A中执行:
1 | $ ssh username@localhost -p1111 |
这样就成功的登陆了内网的主机了。
功能优化
上面的做法其实有一个问题,就是反向ssh可能会不稳定,主机B对服务器A的端口映射可能会断掉,那么这时候就需要主机B重新链接,而显然远在外地的我无法登陆B。。。这其实有一个非常简单的解决方案,就是用autossh替代步骤2中的ssh:
1 | $ autossh -M 2222 -NfR 1111:localhost:22 username@servername -p 22 |
后面的参数跟ssh都一样,只是多了一个-M参数,这个参数的意思就是用本机的2222端口来监听ssh,每当他断了就重新把他连起来。。。不过man文档中也说了,这个端口又叫echo port,他其实是有一对端口的形式出现,第二个端口就是这个端口号加一。因此我们要保证这个端口号和这个端口号加一的端口号不被占用。
参考资料
BlueLake博客主题的详细配置
2021年2月3日更新:
BlueLake主题主题写了有些年头了,随着Hexo升级到5.X,BlueLake很多配置已经过时,在使用中难免出现问题。
所以,我利用工作之余抽了些时间进行了大改版,主题模板引擎由Jade(Pug)换成了EJS,以landscape为原型进行二次开发;保留BlueLake主题老版本的其他功能,如原生JS实现站内搜索功能,本地分享等;新添加了一些新的功能,如打赏模块,集成新的三方评论等等。
说了这么多不如你亲自体验来的直接,BlueLake主题地址:https://github.com/chaooo/hexo-theme-BlueLake。
A Fork in the Road — CM's last blog
Cyanogenmod 在他们的官网发布了最后一篇博客 A Fork in the Road 后,Cyanogenmod 官网和博客域名的 DNS 解析就被停了。
Interative 调速器有关参数分析
Interative
是目前常用的一种 CPU 调速器,其特点是 CPU 频率是根据负载实现交互式反应。但是与ondemand
和conserative
不同的是,interative
拥有一些不同的参数配置方式。
adb设备信息查询修改刷机等命令
ADB很强大,记住一些ADB命令有助于提高工作效率。
通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等
Android 的网络感叹号
从 Android L 开始,原生和 CM 的 ROM 用户就会发现,状态栏的网络信号莫名多了一个感叹号。而且,有的时候明明连着 WIFI 用得好好的,却突然跳到数据流量。